2012-01-22 3 views
2

Предположит, у вас есть класс NonCopyableизбегая неявное копирование с отключенным конструктором копирования

class NonCopyable 
{ 
public: 
    NonCopyable(int n){} 
    ~NonCopyable(){} 
    [...] 

private: 
    [members...] 

private: 
    NonCopyable(const NonCopyable&); //disabled (no definition) 
    NonCopyable& operator= (const NonCopyable&); //disabled (no definition) 
}; 

Для этого класса, это нелогично иметь его копию, таким образом, конструктор копирования и оператор присваивания отключены.

Однако, когда вам нужен вектор NonCopyables объектов:

std::vector<NonCopyable> m_V; 
int n; 
m_V.push_back(NonCopyable(n)); 

Здесь вы неявно вызывать конструктор копирования.

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

Мой вопрос: Есть ли способ обойти это? Какое общее решение этой проблемы?

+2

Ваш вопрос, кажется ... –

+0

Серьезный вопрос, если это нелогично иметь «как я могу использовать не Copyable объект в ситуации, когда мне нужно скопировать этот объект?» копирует вне вектора, почему бы лучше иметь копии, если они находятся внутри вектора? :) –

+0

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

ответ

4

У C++ 11 есть решение, применимое ко многим классам, не подлежащим копированию: сделать класс перемещаемым (а не скопированным) и использовать emplace_back для добавления новых элементов в вектор.

Если вам нужно что-то придумать с помощью C++ 03, возможно, вы сможете найти способ реализовать копирование «пустых» объектов NonCopyable (и использовать идею Luchian для ограничения этой операции), а также найти способ реализации swap , Тогда вы можете сделать:

std::vector<NonCopyable> m_V; 
int n; 
m_V.push_back(NonCopyable()); 
NonCopyable(n).swap(m_V.back()); 
+0

Может быть вопрос о нобе, но я всегда работал с C++ 03. Как я могу начать работу с C++ 11? – xcrypt

+0

Проверьте документацию вашего компилятора, например, с gcc, это '-std = C++ 0x'. –

1

Вы можете сделать vector другой класс:

class NonCopyable 
{ 
    friend std::vector<NonCopyable>; 
public: 
    NonCopyable(int n){} 
    ~NonCopyable(){} 

private: 
    NonCopyable(const NonCopyable&) {}; 
    NonCopyable& operator= (const NonCopyable&) {}; 
}; 

или вы могли бы иметь vector умных указатели на класс.

EDIT:

я мог бы неправильно понял вопрос. Если вы не хотите копировать класс (моя первоначальная догадка заключалась в том, что вы не хотели, чтобы копии были общедоступными), вы должны определенно использовать интеллектуальные указатели.

+1

Вам также требуется определение для этих копий. –

+0

Выполнение 'vector'' friend' просто вызовет ошибки компоновщика, если для конструктора копирования действительно не существует. – sth

+0

@SteveJessop Я просто скопировал код, но да, им нужны определения. –

Смежные вопросы