【问题标题】:c++ reference to an inner class inside an outer classc ++对外部类内部的内部类的引用
【发布时间】:2015-06-02 15:23:41
【问题描述】:

只是出于好奇,是否可以声明对内部类的引用 一个外部类:

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 而不是指针来保证 BA 中的存在。)

编辑

我有一个问题,为什么我想这样做,这是我的目标。让我们想象一下 class B 包含大量数据并需要大量内存。我不 想要有很多 B 的副本,否则我会用完内存。现在我有两个 类CD 都继承自A。我希望他们与 B 的相同实例。我可以用指针来做到这一点,但正如我之前所说的那样 确保在某处至少存在一个B,所以我认为通过使用 参考我将能够保证这一点。我也希望B 成为一个内在 类,这样我就不会污染我的代码。感谢您的帮助,我现在使用右值 参考,我的代码如下所示:

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);
}

但它不能编译。

【问题讨论】:

  • 您似乎将两个问题拼凑在一起,并提出了一个非问题。你到底在问什么?
  • @juanchopanza 我没有弄错两个问题......我的句子是括号只是为了解释我为什么问我的问题......所以我不明白反对意见
  • 是的,您可以这样做。但是请记住,只要您有一个引用是类成员,这意味着编译器无法为该类型合成赋值运算符,虽然您可以定义自己的,但通常很难让它像用户一样工作通常期望。
  • @JerryCoffin,我不确定我是否理解您的评论。你的意思是我确实定义了我自己的operator=,因为如果我不这样做,编译器就不会有效地做到这一点?我真的不在乎它是否会在我 A 被实例化时减慢代码速度(只会执行一次),但我确实关心我是否每次调用例如 b.do_something()A 中形成一个方法。跨度>
  • @PinkFloyd:这意味着编译器根本无法做到这一点,因此你也不能这样做,除非你自己编写operator=,故意忽略引用。你为什么想要那个?该规则有例外,但一般来说,具有引用成员的类应该是不可分配的。

标签: c++ reference inner-classes


【解决方案1】:

没有。

如果您使用右值引用,它将编译

class A
{
   struct B {};
   B&& b;

public:
   A() : b(B()) {}
};

int main()
{
    A a;
}

...但是,令人讨厌的是,这是一个悬空引用,有一条特殊规则禁止成员 b 延长该临时 B() 的生命周期,否则可能会:

[C++11: 12.2/5]: [..] 临时绑定到构造函数的 ctor-initializer (12.6.2) 中的引用成员,直到构造函数退出。 [..]

现在,如果 Bpublic,并且如果 B 对象是从其他地方传入的,那么您已经实现了目标:

struct A
{
   struct B {};
   B& b;

   A(B& b) : b(b) {}
};

int main()
{
    A::B b;
    A a(b);
}

(live demo)

但是,如果做不到这一点,我看不出你还能做些什么来实现这一目标。

不过,它的用处似乎有限;只要有一个真正的B 成员!

【讨论】:

  • 太好了,谢谢……我真的需要更好地理解这个右值引用……如果我不得不使用指针,这将允许我避免使用 newdelete .
  • 我怀疑你的右值引用成员会消耗 B() 临时的生命周期。还不如在类内有一个值副本
  • @KABoissonneault:这个“怀疑”从何而来?
  • @PinkFloyd:最好有一个实际的B 成员。但是,当然,你可以做到这一点......
  • @LightnessRacesinOrbit 因为 const 引用成员不会根据标准扩展临时对象的生命周期。我找不到任何提到右值引用成员的工作方式有任何不同的内容。
【解决方案2】:

如果您希望在复制的成员之间共享对象,请使用 std::shared_ptr。 这是保证 B 对象对于所有使用它的 A 对象都持久存在的唯一标准方法。

【讨论】:

  • 谢谢,这是我的猜测,但由于 shared_ptr 可能为 NULL,我无法保证 B 存在...
  • 它是私人会员。如果您从不将其分配给 null,则它不会为 null。
猜你喜欢
  • 1970-01-01
  • 2011-03-10
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 2013-04-26
  • 2014-01-26
相关资源
最近更新 更多