我搜索了一些SO文章,但还没有找到任何可以解决我问题的东西。如果这个答案确实已存在,请道歉。
首先有点背景......
我想表示具有功能“部分”的设备,其中功能具有分层树状结构。而不是像
那样有大量的扁平化功能DeviceReferenceCheck(),
DeviceRefereceSet(),
DevicePhaseSetX(),
DevicePhaseDefaultsSet...()
我反而喜欢利用嵌套类,所以我可以得到
dev.reference.check()
dev.reference.set()
dev.phase.setx()
dev.phase.defaults.set...()
为此,我尝试使用嵌套类来获取obj.func.subfunction.subsub....()
结构。嵌套类需要引用最外层的类,因为它们需要使用那里提供的读/写函数。
在我的尝试中,我不太了解的第一件事如下......我自己尝试了这个但是由于编译器警告而停止使用它。
class GPIBDevice_Agilent53132A : public GPIBDevice
{
private:
class RefOsc {
public:
// ... snip ...
RefOsc(GPIBDevice_Agilent53132A &parent);
// ... snip ...
} ro;
public:
// ... snip ...
GPIBDevice_Agilent53132A();
// ... snip ...
};
GPIBDevice_Agilent53132A::GPIBDevice_Agilent53132A() : GPIBDevice(), ro(*this)
{
}
编译说:gpibdevice_agilent53132a.cpp(5): warning C4355: 'this' : used in base member initializer list
。
啊哈,我想我自己......聪明的编译器......在初始化列表中使用this
可能不是一个好主意,因为该类尚未完全构建。
问题1:
我上面说的是正确的吗?在封闭类的初始化列表中使用this
为嵌套类提供对封闭类的引用,这是个坏主意吗?我的想法是“是”,但想澄清一下,因为在其他SO线程中我看到了这个方法的使用(Nested Class member function can't access function of enclosing class. Why?)。
我解决这个问题的方法是有一个指向嵌套的成员指针,然后当它实际上在构造函数中时(所以现在可以安全地使用它作为已经构造的类)创建了一个新的内部类,我可以将引用传递给*这没有警告。这是标准的做法吗?
继续......
私有嵌套类的原因是btw,我不希望用户能够自己实例化该类。现在,我确实公开了...试图在嵌套类中使用私有构造函数,但编译器告诉我它无法构造类。所以假设封闭类可以看到嵌套的类私有数据成员吗?
问题2: 为什么封闭类不能看到嵌套类私有数据成员/函数?
我的解决方法是让嵌套类将封闭类声明为朋友。这真的有必要吗?
谢谢你的帮助!
答案 0 :(得分:2)
<强>摘要强>
感谢Jan对curiously recurring template pattern的解释。这是一个有趣的方法来了解。
我最终接受了自己的答案,因为我觉得它直接回答了问题。 CRTP方法很好,但没有直接回答问题1&amp; 2,但确实提供了一个很好的选择。
问题1:
这似乎是可能的。感谢mkirci和R. Martinho Fernandes确认我怀疑编译器生成警告的原因以及忽略它是否“安全”。
总结......在构造函数的初始化列表中使用this
并不是最好的想法,因为尚未构造类。正如大家指出的那样,如果使用指针,这可能会导致UB。我决定使用我的工作,使用指向内部类的指针,然后在外部类构造函数中创建它...这样外部类已经创建并且可以将引用传递给内部安全地上课。
问题2:
从C ++标准来看,我在第11.7节中找到了(经过大量挖掘):
嵌套类是成员,因此具有与任何其他成员相同的访问权限。封闭类的成员对嵌套类的成员没有特殊访问权限;应遵守通常的准入规则(第11条)。
该标准给出了以下示例:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
int g(I* p) {
return p->y; // error: I::y is private
}
};
所以,这是(令人讨厌的)为什么我的外部类不能调用内部类的私有构造函数。我的解决方案是让外部类成为内部类的朋友。即,在上面的示例中,将friend E;
添加到内部类decl。