c++ 引用外部 class 中的内部 class
c++ reference to an inner class inside an outer class
出于好奇,是否可以声明对内部 class 的引用
外部 class :
class A{
private:
class B{
public:
B(double val):val_(val){}
private:
double val_;
};
public:
A(double val):b(B(val)){} /*problem*/
private:
B& b;
};
int main(){
A a(1.0);
}
感觉逻辑上不可能,因为我不知道怎么分配一个
对临时变量的引用。但我想确定一下。 (我想
使用 ref 而不是指针来保证 A
中存在 B
。)
编辑
由于我有疑问为什么要这样做,所以这就是我的目标。让我们想象一下
class B
包含大量数据并需要大量内存。我不
想要 B 的多个副本,否则我会 运行 内存不足。现在我有两个
class C
和 D
都继承了 A
。我希望他们与
B
的相同实例。我可以用指针来做到这一点,但如前所述,我想要
确保至少有一个 B
存在于某处,所以我通过使用
ref 我可以保证这一点。我也想 B
成为一个内
class 这样我就不会污染我的代码。感谢您的帮助,我现在使用右值
参考,我的代码如下所示:
class A{
class B{
public:
B(double val):val_(val){}
private:
double val_;
};
public:
A(double val):b(B(val)){}
A(A const& a):b(a.b){}/*new problem*/
protected:
B&& b;
};
class C: public A{
public:
C(A const& a):A(a){}
};
class D: public A{
public:
D(A const& a):A(a){}
};
int main(){
A a(1.0);
C c(a);
D d(a);
}
但它无法编译。
没有
如果您使用右值引用,它将编译:
class A
{
struct B {};
B&& b;
public:
A() : b(B()) {}
};
int main()
{
A a;
}
…但是,令人恼火的是,这是一个悬空引用,它是一个特殊规则,禁止成员b
延长那个临时B()
的生命周期否则可能:
[C++11: 12.2/5]:
[..] A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits. [..]
现在,如果 B
是 public
,并且如果 B
对象是从其他地方传入的,那么您就达到了目标:
struct A
{
struct B {};
B& b;
A(B& b) : b(b) {}
};
int main()
{
A::B b;
A a(b);
}
(live demo)
但是,如果做不到这一点,我看不出您还能做些什么来实现这一目标。
虽然它的用处似乎有限;只是有一个真正的 B
成员!
如果要在复制的成员之间共享对象,请使用 std::shared_ptr。
这是保证您的 B 对象对于使用它的所有 A 对象持久存在的唯一标准方法。
出于好奇,是否可以声明对内部 class 的引用 外部 class :
class A{
private:
class B{
public:
B(double val):val_(val){}
private:
double val_;
};
public:
A(double val):b(B(val)){} /*problem*/
private:
B& b;
};
int main(){
A a(1.0);
}
感觉逻辑上不可能,因为我不知道怎么分配一个
对临时变量的引用。但我想确定一下。 (我想
使用 ref 而不是指针来保证 A
中存在 B
。)
编辑
由于我有疑问为什么要这样做,所以这就是我的目标。让我们想象一下
class B
包含大量数据并需要大量内存。我不
想要 B 的多个副本,否则我会 运行 内存不足。现在我有两个
class C
和 D
都继承了 A
。我希望他们与
B
的相同实例。我可以用指针来做到这一点,但如前所述,我想要
确保至少有一个 B
存在于某处,所以我通过使用
ref 我可以保证这一点。我也想 B
成为一个内
class 这样我就不会污染我的代码。感谢您的帮助,我现在使用右值
参考,我的代码如下所示:
class A{
class B{
public:
B(double val):val_(val){}
private:
double val_;
};
public:
A(double val):b(B(val)){}
A(A const& a):b(a.b){}/*new problem*/
protected:
B&& b;
};
class C: public A{
public:
C(A const& a):A(a){}
};
class D: public A{
public:
D(A const& a):A(a){}
};
int main(){
A a(1.0);
C c(a);
D d(a);
}
但它无法编译。
没有
如果您使用右值引用,它将编译:
class A
{
struct B {};
B&& b;
public:
A() : b(B()) {}
};
int main()
{
A a;
}
…但是,令人恼火的是,这是一个悬空引用,它是一个特殊规则,禁止成员b
延长那个临时B()
的生命周期否则可能:
[C++11: 12.2/5]:
[..] A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits. [..]
现在,如果 B
是 public
,并且如果 B
对象是从其他地方传入的,那么您就达到了目标:
struct A
{
struct B {};
B& b;
A(B& b) : b(b) {}
};
int main()
{
A::B b;
A a(b);
}
(live demo)
但是,如果做不到这一点,我看不出您还能做些什么来实现这一目标。
虽然它的用处似乎有限;只是有一个真正的 B
成员!
如果要在复制的成员之间共享对象,请使用 std::shared_ptr。 这是保证您的 B 对象对于使用它的所有 A 对象持久存在的唯一标准方法。