其他分享
首页 > 其他分享> > c-如果它们具有私有副本构造函数,为什么不能初始化对象数组?

c-如果它们具有私有副本构造函数,为什么不能初始化对象数组?

作者:互联网

在执行C项目时,我遇到了一些意外的和令人沮丧的行为.我的实际代码有点复杂,但是以下示例也将其捕获:

class Irritating
{
    public:  Irritating() {}
    private: Irritating(const Irritating& other) {}
};

const Irritating singleton;                // Works just fine.
const Irritating array[] = {Irritating()}; // Compilation error.

int main()
{
    return 0;
}

尝试编译它会产生以下错误(以防万一,抛出GCC版本):

[holt@Michaela irritating]$g++ --version
g++ (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[holt@Michaela irritating]$g++ test.cpp
test.cpp:4:11: error: ‘Irritating::Irritating(const Irritating&)’ is private
test.cpp:8:41: error: within this context
[holt@Michaela irritating]$

不幸的是,令人讨厌的对象是来自外部库并且不在我的控制范围内.我当前的解决方法是使用一个指针数组.它可以工作,但感觉有点破烂,并增加了不必要的间接层.有一个更好的方法吗?

同样:数组是常量和全局的(在实际代码中,是类静态的);为什么不将其初始化到位?这是预期的C行为,还是GCC的错误/怪癖?

更新:安装Clang只是为了查看它是否与GCC一致.可悲的是,它做到了:

[holt@Michaela irritating]$clang test.cpp
test.cpp:8:29: warning: C++98 requires an accessible copy constructor for class 'Irritating' when binding a reference to a temporary; was private
      [-Wbind-to-temporary-copy]
const Irritating array[] = {Irritating()};
                            ^
test.cpp:4:11: note: declared private here
        private: Irritating(const Irritating& other) {}
                 ^
test.cpp:8:29: error: calling a private constructor of class 'Irritating'
const Irritating array[] = {Irritating()};
                            ^
test.cpp:4:11: note: declared private here
        private: Irritating(const Irritating& other) {}
                 ^
1 warning and 1 error generated.
[holt@Michaela irritating]$

解决方法:

因为通过= {…}语法指定的初始化程序通过复制初始化来初始化单个数组元素.参见8.5 / 12(C 03)

The initialization that occurs in argument passing, function return,
throwing an exception (15.1), handling an exception (15.3), and
brace-enclosed initializer lists (8.5.1) is called copy-initialization

复制初始化需要复制构造函数(即使它实际上不会使用它).

实际上,如果通过公开复制构造函数使代码编译,则编译器可能最终会在不使用复制构造函数的情况下就地初始化数组元素.但是,在这种情况下,抽象语言的形式规则要求进行复制初始化.

标签:c,initialization,g,copy-constructor
来源: https://codeday.me/bug/20191012/1903285.html