其类具有一些 ctor / dtor 的数组对象初始化
我想通过使用初始化语句来实现数组对象初始化,如下所示。
TestClass array[5] = {
TestClass("test1"),
TestClass("test2"),
TestClass("test3"),
TestClass("test4"),
TestClass("test5")
};
根据一些权威书籍,如ARM(带注释的C++参考手册),似乎说这是初始化具有构造函数/析构函数的对象数组的方法。接下来,我刚刚创建了以下示例代码,看看会发生什么。
#include <iostream>
#include <sstream>
#include <string>
class TestClass
{
public:
TestClass(const char* name) : name_(name)
{
std::cout << "Ctor(const char*) : " << name_ << std::endl;
}
~TestClass()
{
std::cout << "Dtor() : " << name_ << std::endl;
}
TestClass() : name_("")
{
}
void print()
{
std::cout << "obj:" << name_ << std::endl;
}
private:
TestClass(const TestClass& rhs);
std::string name_;
};
int main()
{
TestClass array[5] = {
TestClass("test1"),
TestClass("test2"),
TestClass("test3"),
TestClass("test4"),
TestClass("test5")
};
for (unsigned int i = 0; i < sizeof(array)/sizeof(array[0]); ++i) {
array[i].print();
}
return EXIT_SUCCESS;
}
至于使用 GNU GCC (4.1.2) 编译上述源代码的第一次尝试,它失败了,生成了如下所示的内容。
error: ‘TestClass::TestClass(const TestClass&)’ is private
所以我明白这意味着为了允许对象数组初始化,它需要“复制构造函数”。然后我尝试通过引入用户定义的(公共)复制构造函数来编译上述代码,如下所示。
TestClass::TestClass(const TestClass& rhs) : name_(rhs.name_)
{
std::cout << "Copy Ctor : " << name_ << std::endl;
}
我可以成功编译源代码。但是,当我执行上面构建的程序时,我得到了以下输出。
Ctor(const char*) : test1
Ctor(const char*) : test2
Ctor(const char*) : test3
Ctor(const char*) : test4
Ctor(const char*) : test5
obj:test1
obj:test2
obj:test3
obj:test4
obj:test5
Dtor() : test5
Dtor() : test4
Dtor() : test3
Dtor() : test2
Dtor() : test1
我很好奇的是,
为什么我们不能将复制构造函数声明为私有?
为什么不调用用户定义的复制构造函数(我预计输出应该在某处包含“Copy Ctor : xxxx”。但我无法得到这一点。所以我明白用户定义的复制构造函数尚未被调用)
实际上,我不太确定上面的内容是否特定于 GNU GCC 还是 C++ 语言规范...如果你们中的一些人能给我上面的正确指针,我将不胜感激。
I would like to realize array objects initialization by using the initialization statement as follows.
TestClass array[5] = {
TestClass("test1"),
TestClass("test2"),
TestClass("test3"),
TestClass("test4"),
TestClass("test5")
};
According to some authoritative book like ARM (annotated reference manual) for C++, it seems that it says that this is the way to initialize object array which has constructor / destructor. Following this, I've just created the following sample code and see what happens.
#include <iostream>
#include <sstream>
#include <string>
class TestClass
{
public:
TestClass(const char* name) : name_(name)
{
std::cout << "Ctor(const char*) : " << name_ << std::endl;
}
~TestClass()
{
std::cout << "Dtor() : " << name_ << std::endl;
}
TestClass() : name_("")
{
}
void print()
{
std::cout << "obj:" << name_ << std::endl;
}
private:
TestClass(const TestClass& rhs);
std::string name_;
};
int main()
{
TestClass array[5] = {
TestClass("test1"),
TestClass("test2"),
TestClass("test3"),
TestClass("test4"),
TestClass("test5")
};
for (unsigned int i = 0; i < sizeof(array)/sizeof(array[0]); ++i) {
array[i].print();
}
return EXIT_SUCCESS;
}
As for the first trial to compile the above source code using GNU GCC (4.1.2), it failed by generating something like the following.
error: ‘TestClass::TestClass(const TestClass&)’ is private
So I understood that this means that in order to allow object array initialization, it would require 'copy constructor'. Then I tried to compile the above code by introducing user-defined (public) copy constructor as follows.
TestClass::TestClass(const TestClass& rhs) : name_(rhs.name_)
{
std::cout << "Copy Ctor : " << name_ << std::endl;
}
I could successfully compile the source code. However, when I execute the program which has been built the above, I got the following output.
Ctor(const char*) : test1
Ctor(const char*) : test2
Ctor(const char*) : test3
Ctor(const char*) : test4
Ctor(const char*) : test5
obj:test1
obj:test2
obj:test3
obj:test4
obj:test5
Dtor() : test5
Dtor() : test4
Dtor() : test3
Dtor() : test2
Dtor() : test1
What I'm curious to know is the following,
Why we cannot make the copy constructor declared as private?
Why the user-defined copy constructor is not invoked (I expected that the output should have included "Copy Ctor : xxxx" somewhere. But I couldn't get that. So I understood the user-defined copy constructor has not been invoked.)
Actually, I'm not really sure whether the above is specific to GNU GCC or this is C++ language specification... It would be appreciated if some of you could give me the correct pointer on the above.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编译器忽略了副本,但复制构造函数仍然必须可访问。
The compiler elides the copy, but the copy-constructor still has to be accessible.
无论编译器是否使用复制构造函数,它都必须是可访问的 - 即它不能是私有的。在这种情况下,编译器可以通过直接使用 const char * 构造函数来避免使用复制构造函数,但它仍然需要一个可访问的复制构造函数。这是 ARM 中没有涵盖的事情,它已经过时了。
Whether of not the copy constructor is used by the compiler, it must be accessible - i.e. it must not be private. In this case, the compiler could avoid using the copy constructor, by using the const char * constructor directly, but it still needs an accessible copy ctor. This is the kind of thing not covered in the ARM, which is way out of date.