член класса как ссылка на другой: сбой в операторе присваивания - PullRequest
2 голосов
/ 20 марта 2012

У меня есть класс 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

Ответы [ 2 ]

4 голосов
/ 20 марта 2012

Это законно?

Нет, потому что анонимные структуры не являются законными.Если вы назовете его, он будет вызывать неопределенное поведение , если foo не будет правильно инициализирован первым (в частности, вы не можете прочитать элементы x и y, если инициализировали data).

Как только я все это исправлю, какие еще проблемы это вызовет?

Ну, во-первых, наличие каких-либо опорных элементов запрещает генерацию оператора присваивания.Это может или не может быть важно для вас.И затем сгенерированный компилятором конструктор копирования укусит вас: он просто слепо копирует все элементы, заканчиваясь копией элемента foo и ссылочных членов, ссылающихся на foo оригинального объекта .Если этот оригинальный объект имеет более короткое время жизни, произойдут плохие вещи.Возможно, вы захотите написать конструктор копирования или рассмотреть альтернативные проекты без ссылочных элементов.

0 голосов
/ 20 марта 2012

Сначала инициализируйте членов профсоюза, либо поведение IIRC неопределено. Затем вы также можете инициировать ссылки на членов вашего профсоюза.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...