【问题标题】:Default assignment operator in inner class with reference members具有引用成员的内部类中的默认赋值运算符
【发布时间】:2010-12-22 09:46:38
【问题描述】:

我遇到了一个我不明白的问题,我希望这里有人可以提供一些见解。简化代码如下(原代码是自定义队列/队列迭代器实现):

class B
{
public:
    B() {};
    class C
    {
    public:
        int get();
        C(B&b) : b(b){};
    private:
        B& b;
    };
public:
    C get_c() { return C(*this); }
};

int main()
{
    B b;
    B::C c = b.get_c();


    c = b.get_c();
    return EXIT_SUCCESS;
}

编译时出现以下错误:

foo.cpp: In member function 'B::C& B::C::operator=(const B::C&)':
foo.cpp:46: error: non-static reference member 'B& B::C::b', can't use default assignment operator
foo.cpp: In function 'int main()':
foo.cpp:63: note: synthesized method 'B::C& B::C::operator=(const B::C&)' first required here

我可以通过使用两个单独的 C 变量来解决这个问题,因为它们应该是独立的“C”对象,但这只会隐藏问题(我仍然不明白为什么我不能这样做)。

我认为原因是无法复制引用,但我不明白为什么。我需要提供自己的赋值运算符和复制构造函数吗?

【问题讨论】:

    标签: c++ reference assignment-operator


    【解决方案1】:

    这个问题与内部类无关。在 C++ 中,您不能(重新)分配引用 - 它们需要在定义时进行初始化。

    一个更简单的例子是:

    class B
    {
    public:
        B(int& i) : ir(i) {};
    
        int& ir;
    };
    
    
    int main()
    {
        int i;
        B b(i);      // Constructor - OK
    
        int j;
        B bb = B(j); // Copy constructor - OK
    
        bb = b;      // Assignment - Error
        return 0;
    }
    

    【讨论】:

    • 呸,你当然是对的,我不敢相信我错过了明显的解释。早上应该多喝点咖啡:D
    • +1。我发现在谈论引用时习惯性地使用“绑定”而不是“分配”可以帮助我避免犯这个错误。
    • 现在,我要重新分配一个引用,当然它会编译: int a = 3;诠释 b = 4; int& ref = a;参考 = b;。因此可以重新分配参考。
    【解决方案2】:

    一个引用在被赋予初始值后不能被改变。这意味着不可能编写更改引用成员值的赋值运算符。如果您需要这样做,请使用指针而不是引用。

    【讨论】:

    • 这实际上是可能的。详情请查看我的评论。
    【解决方案3】:

    实际上,有一个解决方案。你可以implement operator= in terms of copy construction,它会起作用的:) 对于这种情况,这是一种非常有能力的技术。假设您确实想支持分配。

    【讨论】:

    • 在赋值运算符中调用析构函数是一个非常糟糕的编程习惯。
    • 首先感谢您的回答,我自己已经达到了这个解决方案,但省略了自分配检查和显式析构函数调用。您注意到您不建议使用它(我同意您的推理),考虑到这些缺点,是否有首选的实现方式?
    • 您的链接已损坏,现在您的回答无效。
    【解决方案4】:

    C++ 没有“内部类”,只有嵌套的类声明。 “内部类”是我认为在其他主流语言中找不到的 Java 主义。在 Java 中,内部类是特殊的,因为它们包含对包含类型对象的隐式不可变引用。要在 Java 中实现与 C++ 的嵌套声明等效,需要使用静态内部类;静态内部类不包含对声明类型对象的引用。

    【讨论】:

      猜你喜欢
      • 2012-01-27
      • 2011-12-15
      • 2021-06-28
      • 2014-10-28
      • 2014-04-21
      • 2012-09-19
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      相关资源
      最近更新 更多