У меня есть иерархия классов, и я хочу запретить делать это:
Foo *f = new Foo();
Bar *b = new Bar();
f = b;
где Foo
это суперкласс Bar
, Делать это будет нарезать Bar
часть объекта. Я знаю, что вы можете решить это, сделав operator=
закрытый, но возможно ли запретить использование оператора присваивания, только если они имеют разные типы?
Как сделать operator=
частный, но все еще позволяющий это:
Bar *b1 = new Bar();
Bar *b2 = new Bar();
b1 = b2;
Предположим, что подклассы будут сделаны для Bar
также.
Поскольку вы говорите о нарезке, я предполагаю, что вы на самом деле пытаетесь предотвратить это:
Foo f;
Bar b;
f = b;
В этом случае, да, вы можете предотвратить присвоение, сделав соответствующий оператор = частным.
Вы не можете предотвратить назначение указателей, но обратите внимание, что назначение указателей в любом случае не приведет к нарезке.
Это вне вашей досягаемости: пользовательские операторы должны принимать как минимум один параметр пользовательского (не встроенного) типа. Поскольку указатели являются встроенными типами, вам здесь не повезло. f = b
будет законным независимо от того, что вы делаете.
В вашем примере нарезки не будет:
Foo *f = new Foo();
Bar *b = new Bar();
f = b;
Вы назначаете указатель, а не значение. Указатель f и указатель b имеют одинаковый размер (размер указателя на архитектуре, на которой вы работаете), поэтому они всегда будут вписываться друг в друга без нарезки. Сами объекты не затрагиваются этим назначением и не нарезаются.
Но это приведет к утечке «нового Foo ()». После назначения и f, и b будут указывать на «new Bar ()», и у вас не останется указателя на «new Foo ()», с помощью которого вы сможете удалить его.
Могу ли я предложить вам использовать std :: unique_ptr вместо необработанных указателей. Это позаботится об удалении для вас.
std::unique_ptr<Foo> newInstance()
{
return new Foo();
}