2011-05-30 25 views
8

我想通过使用初始化语句来实现数组对象的初始化,如下所示。数组对象初始化的类有一些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 

什么我很想知道的是下面的,

  1. 为什么我们不能声明为private的拷贝构造函数?

  2. 为什么没有调用用户定义的拷贝构造函数(我期望输出应该在某处包含“Copy Ctor:xxxx”,但我无法得到它,所以我理解了用户定义的拷贝构造函数没有被调用。)

其实,我真的不知道以上是否是特定于GNU GCC或这是C++语言规范......这将不胜感激,如果你们中的一些可以给我正确的上面的指针。

+2

您可能想用'-fno-elide-constructors'进行_test_测试。 – 2011-05-30 13:24:43

+0

类似的情况在这里:[奇怪的复制初始化行为,不调用复制构造函数!](http://stackoverflow.com/questions/6163040/strange-behavior-of-copy-initialization-doesnt-call-复制构造函数) – Nawaz 2011-05-30 13:28:44

回答

3

编译器是否使用了复制构造函数,它必须是可访问的 - 即它不能是私有的。在这种情况下,编译器可以通过直接使用const char *构造函数来避免使用复制构造函数,但它仍然需要一个可访问的copy ctor。这是ARM中没有涉及的那种事情,它已经过时了。

+0

谢谢你的明确答案。现在我可以清楚地说到。 – Smg 2011-05-30 14:07:04

4

编译器将复制副本删除,但复制构造函数仍然必须可访问。

+0

谢谢你的明确答案。正确理解。 – Smg 2011-05-30 14:06:17