2014-11-11 3 views
0

Предположим, у меня есть 2 класса Foo и Cook и Book - это структура.Может ли 2 класса делиться одной структурой?

Ранее Book глобальная переменная, и я хотел бы изменить его, чтобы принадлежать Foo, так что я могу иметь много Foo со своими собственными Book.

Cook читает Book, но Foo время от времени обновляет значение Book.

Следующий код, который я тестировал, не работает. Я очень новичок в C++, я не понимаю, почему это не работает.

class Foo { 
private: 
    Book book; 
    Cook cook; 
public: 
    Foo(); 
    virtual ~Foo(); 
}; 

class Cook { 
private: 
    Book * book; 
public: 
    Cook(); 
    virtual ~Cook(); 
    void setBook(Book * book); 
}; 

Затем внутри конструктора Foo «s есть: cook.setBook(&book);

+2

«Не работает» означает, что именно? – tadman

+0

Он компилируется, но дает неправильный расчет. Поэтому я думаю, что книга при доступе из Кука не отражает обновленную стоимость. –

+5

То, как вы случайно обмениваетесь указателем на частную собственность другого объекта, действительно плохая идея, которая неизбежно приведет к множеству проблем. Лучше всего создавать уникальную «книгу» и передавать ее в оба из них, где ни один из них не принадлежит, но владение управляется чем-то вроде ['std :: shared_ptr'] (http://en.cppreference.com/w/cpp/memory/shared_ptr9), если вы не можете установить сильную политику собственности. Другой подход заключается в том, чтобы 'Cook' как класс друга' Foo', чтобы он мог получать нужные ему данные, не требуя собственного указателя. – tadman

ответ

1

Что вы делаете должно работать нормально, хотя я не могу согласиться с достаточно tadman, что вы должны использовать std::shared_ptr.

Если вы видите, что ваши значения выходят из синхронизации, вероятно, вы перезаписали Foo.book, но это изменение не было распространено на Foo.cook.book.

Возможно лучше дизайн будет:

class Foo { 
private: 
    Book book; 
    Cook cook; 
    Book& getBook(); 
public: 
    Foo() : cook(std::bind(getBook,this)); 
    virtual ~Foo(); 
}; 

class Cook { 
private: 
    std::function<Book&()> _memfunptr; 
public: 
    Cook(std::function<Book()> memfunptr): _memfunptr(memfunptr); 
    virtual ~Cook(); 
}; 

Отсюда любое время вы хотели бы сослаться Foo.book внутри Foo.cook вы могли бы просто использовать Cook._memfunptr для доступа к нему.

Как можно заметить, некоторые из вас могут быть связаны с реализацией класса? У вас должна быть точка с запятой в конце каждой области class, и вы должны определить конструктор Cook. Cook();не .

+0

спасибо! Я обновил опечатку –