Как запретить другим создавать новый экземпляр вашего класса в стеке? - PullRequest
4 голосов
/ 27 октября 2011

Предположим, вы пишете класс A, причем конструктор является закрытым (чтобы другие не могли его создать в стеке), а затем однажды другой разработчик добавил новый ctor, скажем A (int), и захотел бы использовать его в main (): 1001 *

A a (1)

чтобы создать его в стеке. Как вы можете предотвратить это?

мое решение:

Объявить открытый конструктор

  A(void& input )
   {
 Cerr << “please do not create it on stack” << endl ; 
  exit(1);
   }

Я не уверен, что это правильно?

спасибо

Ответы [ 4 ]

8 голосов
/ 27 октября 2011

Как говорят другие, вы не можете помешать людям, которые могут редактировать ваш класс, заставить его делать почти все что угодно ... НО ...

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

Примерно так:

class DoNotStackConstruct {
protected:
    DoNotStackConstruct(const char* dummy) {}
};

class A : protected DoNotStackConstruct {
private:
    A () : DoNotStackConstruct ("PLEASE make all A constructors private!") {
       // your code here
    }
public:
    static std::tr1::shared_ptr<A> newA() {
        return std::tr1::shared_ptr<A>(new A);
    }

/* ... a bunch of code ... */
/* ... then someone later adds the following ... */

public:
    A (int i) {
        // can't force them to make it private, but...
        // this won't compile without mentioning DoNotStackConstruct
    }
};

Как только вы начнете использовать C ++ 11, появятся "делегирующие конструкторы", и этот трюкбудет немного меньше зубов:

Могу ли я вызвать конструктор из другого конструктора (сделать цепочку конструктора) в C ++?

Тогда они смогут делегироватьA() без посещения строки исходного текста и копирования "эй, не делайте ваш конструктор публичным!"текст.Но по умолчанию они все равно получат ошибку компилятора при первой попытке.

7 голосов
/ 27 октября 2011

Добавьте комментарий, который говорит что-то вроде этого:

class A
{
    private:
        // This is private on purpose to prevent allocation on the stack.
        // We'll fire you if you ever write a new constructor that isn't private.
        A();
};

Этот комментарий в основном ненормативен, но он указывает на важную концепцию.Соглашения о коде, такие как запрещение выделения стеков, должны выполняться коллегиально.Как уже говорили другие, теоретически кто-то может изменить код так, как он хочет.Но хороший процесс рецензирования поможет держать это под контролем.ИМХО, это гораздо более экономически выгодно, чем некоторые хитрые трюки с компилятором, которые новые сотрудники могут не обязательно понимать.

5 голосов
/ 27 октября 2011

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

1 голос
/ 27 октября 2011

Я думаю, что вам нужно решение следующих шагов:

  1. Предоставить конструктору доступ "private".
  2. Создать статическую функцию, не являющуюся членом, которая создает экземпляр новымили malloc и возвращает его.
  3. Используйте функцию для создания экземпляра класса.

Я уверен, что этот шаг может быть решением вашего вопроса.

...