簡體   English   中英

類成員引用另一個:賦值運算符崩潰

[英]class member as reference to another: crash in assignment operator

我有一個Bar類,其中引用了其中一個成員( Bar::foo )的內部:

#include<vector>
#include<algorithm>

struct Foo{
    int x, y;
};

struct Bar{
    Foo foo;
    int &x, &y;
    Bar(): x(foo.x), y(foo.y){}
    // copy constructor and assignment operator
    Bar(const Bar& other): foo(other.foo), x(foo.x), y(foo.y){}
    Bar& operator=(const Bar& other){ foo=other.foo; return *this; }
};

int main(void){
    std::vector<Bar> a, b;
    Bar p; p.x=0; p.y=0;
    a.push_back(p);
    std::copy(a.begin(),a.end(),b.begin());
}

使用g++編譯(沒有任何特殊選項)時,賦值運算符崩潰。 為什么?

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400b29 in Bar::operator= (this=0x0, other=...) at ref2.cpp:14
14      Bar& operator=(const Bar& other){ foo=other.foo; return *this; }
(gdb) bt
#0  0x0000000000400b29 in Bar::operator= (this=0x0, other=...) at ref2.cpp:14
#1  0x00000000004016a0 in std::__copy_move<false, false, std::random_access_iterator_tag>::__copy_m<Bar*, Bar*> (
__first=0x405010, __last=0x405030, __result=0x0) at /usr/include/c++/4.6/bits/stl_algobase.h:329
#2  0x000000000040148d in std::__copy_move_a<false, Bar*, Bar*> (__first=0x405010, __last=0x405030, __result=0x0)
at /usr/include/c++/4.6/bits/stl_algobase.h:384
#3  0x0000000000401157 in std::__copy_move_a2<false, __gnu_cxx::__normal_iterator<Bar*, std::vector<Bar, std::allocator<Bar> > >, __gnu_cxx::__normal_iterator<Bar*, std::vector<Bar, std::allocator<Bar> > > > (__first=..., __last=..., 
__result=...) at /usr/include/c++/4.6/bits/stl_algobase.h:422
#4  0x0000000000400cc0 in std::copy<__gnu_cxx::__normal_iterator<Bar*, std::vector<Bar, std::allocator<Bar> > >, __gnu_cxx::__normal_iterator<Bar*, std::vector<Bar, std::allocator<Bar> > > > (__first=..., __last=..., __result=...)
at /usr/include/c++/4.6/bits/stl_algobase.h:454
#5  0x00000000004009f4 in main () at ref2.cpp:21

這合法嗎?

不可以,因為匿名結構不合法。 如果您將其命名, 除非首先正確初始化foo (特別是如果初始化data您將無法讀取xy成員),否則它將調用未定義的行為。

一旦解決所有問題,這還會導致什么其他問題?

好吧,首先,擁有任何種類的參考成員都會抑制賦值運算符的生成。 這對您可能並不重要。 然后,由編譯器生成的副本構造函數將咬住您:它只是盲目地復制所有成員,最后是foo成員和引用原始對象foo的引用成員的副本。 如果此原始對象的壽命較短,則會發生不良情況。 您可能想編寫一個復制構造函數,或考慮沒有參考成員的替代設計。

首先初始化您的工會成員,否則是IIRC未定義的行為。 然后,您也可以初始化對您的工會成員的引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM