在C ++ 11之前,我们只能对整型或枚举types的静态常量成员进行类内初始化。 Stroustrup在他的C ++ FAQ中讨论了这个问题 ,举例如下: class Y { const int c3 = 7; // error: not static static int c4 = 7; // error: not const static const float c5 = 7; // error: not integral }; 以下推理: 那么为什么这些不便的限制存在? 一个类通常在头文件中声明,而头文件通常包含在许多翻译单元中。 但是,为了避免复杂的链接器规则,C ++要求每个对象都有唯一的定义。 如果C ++允许将需要作为对象存储在内存中的实体的类定义中断,那么该规则将被破坏。 但是,C ++ 11放宽了这些限制,允许非静态成员的类内初始化(§12.6.2/ 8): 在非委托构造函数中,如果给定的非静态数据成员或基类不是由mem-initializer-id指定的(包括由于构造函数没有ctor初始值设定项而没有mem-initializer-list的情况)而实体不是抽象类(10.4)的虚拟基类 如果实体是一个非静态数据成员,它具有一个括号或等于初始值设定项 ,则该实体按照8.5中的规定进行初始化; 否则,如果实体是变体成员(9.5),则不执行初始化; 否则,实体将被默认初始化(8.5)。 […]
下面的代码不能用gcc编译,而是用Visual Studio编译: template <typename T> class A { public: T foo; }; template <typename T> class B: public A <T> { public: void bar() { cout << foo << endl; } }; 我得到的错误: test.cpp:在成员函数'void B :: bar()'中: test.cpp:11:错误:'foo'未在此范围内声明 但应该是! 如果我改变bar void bar() { cout << this->foo << endl; } 那么它编译,但我不认为我必须这样做。 在C ++的官方规范中是否有这样的东西,GCC在这里,还是只是一个怪癖?
这是一个简单的例子来说明这个问题: class A {}; class B { B(A& a) : a(a) {} A& a; }; class C { C() : b(a) {} A a; B b; }; 所以B负责更新C的一部分。我通过lint运行代码,并发出关于引用成员的声音: lint#1725 。 这里谈到关于默认的副本和分配,这是公平的,但默认的副本和分配也是坏指针,所以没有什么优势。 我总是尽可能地使用引用,因为裸指针不确定地引入谁负责删除指针。 我更喜欢通过值embedded对象,但如果我需要一个指针,我使用auto_ptr在拥有指针的类的成员数据,并作为参考传递对象。 我通常只会在指针可能为空或者可能改变时才在成员数据中使用指针。 有什么其他的理由喜欢指针比数据成员的引用? 是否真的说包含引用的对象不应该是可分配的,因为一旦初始化引用不应该被改变?