2010-06-05 5 views
3

При чтении TCPL, У меня проблема, так как refered название, а затем 'частный' класс:Как использовать объект, чей конструктор копирования и назначение копии являются частными?

class Unique_handle { 
private: 
    Unique_handle& operator=(const Unique_handle &rhs); 
    Unique_handle(const Unique_handle &rhs); 
public: 
    //... 
}; 

что используя код:

struct Y { 
    //... 
    Unique_handle obj; 
}; 

и я хочу, чтобы выполнить такие операции:

int main() 
{ 
    Y y1; 
    Y y2 = y1; 
} 

хотя эти кодовые приходят из TCPL, но я до сих пор не получил решение ... Может кто-нибудь мне помочь, оцените.

+0

@coanor: добро пожаловать в переполнение стека. Потратьте несколько минут, чтобы ознакомиться с параметрами форматирования редактора - на данный момент я повторно отформатировал сообщение, чтобы правильно показать код. –

+0

Хм, почему на самом деле это 'Unique_handle' невозможно? То есть почему бы не иметь (копируемое) обращение к уникальному? – mlvljr

+2

@coanor: что вы пытаетесь достичь с ним? Какой смысл создавать уникальный дескриптор, а затем пытаться его скопировать, поэтому он больше не уникален? Что ты пытаешься сделать? – jalf

ответ

6

Как следует из его названия, Unique_handle не предназначено для копирования. Его реализация обеспечивает его, отключая конструктор копирования и оператор присваивания копии.

Одно решение для нескольких экземпляров, имеющих доступ к Unique_handle, удерживает указатель на него и копирует указатель. Затем несколько экземпляров Y указывают на тот же уникальный дескриптор.

Соблюдайте осторожность, однако для правильного управления ресурсами в этом случае.

+0

Большое спасибо, я задал свой вопрос и нашел способ построить такой объект: static Unique_handle * instance() {return new Unique_handle(); } , но кажется неправильным, тогда как я могу определить такой объект снаружи? – coanor

+0

@coanor: прочитайте о реализации шаблона singleton в C++. Есть много подходов - выберите тот, который подходит для ваших нужд. –

+0

О, боже, так вот где мы сейчас? Если вы определяете конструктор частной копии и сожалеете об этом, лучший ответ - сделать его * singleton *? Я плачу за код, который будет написан в ближайшие годы. – jalf

2

Как правило, идиома, заключающаяся в том, что ваш экземпляр-конструктор и оператор присваивания являются частными (и не реализованными), подразумевает, что первоначальный автор этого класса специально не хотел, чтобы этот объект был скопирован.

2

Вы не должны пытаться его скопировать. Но, сказав это ..., вы можете его помнить. Только причина, по которой вы это делаете, это то, что вы знаете, что вы делаете, вы знаете последствия и т. Д. И т. Д. Его обычно выходят за рамки общепринятого. Но вы можете сделать что-то немного ниндзя.

+0

Худший. Совет. Когда-либо. –

+0

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

4

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

Класс намеренно делает так, чтобы ваш код не мог делать то, что вы пытаетесь сделать (по-видимому, потому, что класс не будет функционировать должным образом или копирование в противном случае не имеет смысла). Если вы хотите копировать объекты этого класса, вам нужно будет перепроектировать класс.

Некоторые другие варианты, которые у вас могут быть (что также может не иметь смысла, но это зависит от того, что вы действительно делаете) - передайте указатели на ссылки на объект вместо копирования.

0

Я гугл моего вопроса, и найти способ, чтобы построить такой объект:

статический Unique_handle * экземпляр() {вернуть новый Unique_handle(); }

но кажется неправильным, тогда как я могу определить такой объект снаружи?

В любом случае, спасибо вам за вашу заботу.

0

Вы можете использовать shared_ptr разделять объект:

class Y 
{ 
public: 
    Y(): mHandle(new UniqueHandle()) {} 

private: 
    boost::shared_ptr<UniqueHandle> mHandle; 
}; 

Это так просто.

Если вы не хотите долевой собственности, вы можете использовать boost::scoped_ptr или вновь созданный std::unique_ptr, если у вас есть доступ к нему, а затем реализовать CopyConstructor и AssignmentOperator себя, заботясь о своей семантике.