Как предотвратить внедрение метода, который должен быть не реализован на С++?

Возможный дубликат:
Какой самый надежный способ запретить конструктор копирования на С++?

Предположим, что я хочу сделать класс не скопированным и хочу запретить конструктор и оператор присваивания. Я делаю их частными и оставляю невыполненными:

class Class {
//useful stuff, then
private:
    Class( const Class& ); //not implemented anywhere
    void operator=( const Class& ); //not implemented anywhere
};

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

Теперь, что, если пользователь реализует их? Я имею в виду, что нет реализации, поэтому каждый может добавить свой собственный:

Class::Class( const Class& )
{
    //whatever they want
}

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

Есть ли способ предотвратить внедрение такого метода пользователем и все еще иметь возможность обнаружения непредвиденных вызовов на компиляцию?

Ответ 2

Здесь нет проблем.

Клиент может обеспечить реализацию этих методов так, как им нравится, но компилятор все равно будет жаловаться, поскольку они являются частными.

Теперь вы можете запретить кому-то взломать файл заголовка, изменить его на публичный и связать свои собственные реализации?

Да, предоставьте свои собственные реализации, которые генерируют исключения, ваш гипотетический хакер получит ошибку связи при попытке создания.

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

., не может получить доступ к частному члену объявлен в классе.,.

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

+1 Кстати, интересный вопрос:)

., как указано Xeo, вышесказанное работает только для не templated классов

Ответ 3

Ну, решение похоже на то, как это обычно делается на практике - используйте специальный базовый класс, не копируемый (например, boost:: noncopyable или ваш собственный класс). Например.

class noncopyable
{
    // private
    noncopyable( const noncopyable& ); // not implemented
    noncopyable& operator=( const noncopyable& ); // not implemented

    // no friends, etc
};

Тогда где-то

class A: noncopyable
{
// Anything ...
};

Очевидно, что, поскольку нет друзей noncopyable, его оператор constuctor и присваивания всегда является приватным для всех, поэтому не имеет значения, реализовано это или нет (компилятор вообще отрицает их использование).

Ответ 4

Немного ответа на вопрос, но, возможно, другого подхода, в зависимости от того, что вы пытаетесь достичь.

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

Если это так, не можете ли вы решить свою проблему, имея две сборки?

  • Build One (внутренняя сборка): он создает библиотеку и не ссылается на функции конструктора копирования.

  • Build Two (сборка клиента): какие ссылки в логике построения сборки с утверждениями (из другого файла реализации), так что защита времени выполнения и клиент не могут обеспечить свою собственную реализацию.

Ответ 5

Что вы хотите сделать, называется MUTUAL exclusion.... лучший способ сделать то, что вы хотите, - это... СДЕЛАЙТЕ ДРУГОЙ КЛАСС, КОТОРЫЙ ОСУЩЕСТВЛЯЕТ ФУНКЦИИ → →

и сделать объект этого класса в вашем классе..... таким образом, вы можете получить доступ к функции, НО НЕТ ОДНОЙ МОЖЕТЕ, иначе может действительно попасть в них, так как они не существуют в классе....:) надеюсь, что это отвечает на ваш вопрос