C ++ операторы присваивания вопрос о наследовании - PullRequest
0 голосов
/ 26 апреля 2011

У меня есть два класса - базовый класс A и производный класс B - и я пишу это

A obj;  
B obj2;  
obj = obj2;  

Что бы на самом деле произошло, если бы мне еще не пришлось переопределять какие-либо операторы присвоения?Будет ли это просто скопировать часть A obj2 в obj?Это даже правильно, или ошибка, которую компилятор просто оправдывает?Позволяет ли отношение IS_A выполнить этот оператор?Любая помощь очень ценится.

Ответы [ 5 ]

1 голос
/ 26 апреля 2011
class Base
{
    //Members       
};

class Derived1:public Base
{
    //Members
};

class Derived2:private Base
{
    //Members 
};


int main()
{
    Base obj1;
    Derived1 obj2;
    Derived2 obj3;

    obj1 = obj2;   //Allowed Since Public Inheritance 
    obj1 = obj3;   //Not Allowed, Compiler generates error
}

Когда obj1 = obj2 копируются в obj1 только те члены производного класса obj2, которые унаследованы от базового класса, остальные члены производного класса обрезаются. Это просто потому, что базовый класс obj1 не знает членов класса Derived. Этот феномен называется Object Slicing.

Если у класса есть переменные-члены-указатели, которые должны быть выделены в Heap, obj1 = obj2 создает Shallow Copy, что означает, что переменная-член-указатель внутри obj1 и obj2 теперь будет указывать на одну и ту же память кучи. Итак, что произойдет, если obj2 исправлен ОС, а obj1 все еще используется? Катастрофа! Поэтому overloading = operator и создание Deep copy объектов следует избегать мелких копий.

1 голос
/ 26 апреля 2011

Это, безусловно, разрешено. Он назначит подобъекту A из obj2 значение obj.

Из-за взаимосвязи IS-A практически невозможно предотвратить это во время компиляции, не предотвращая также присвоение экземпляра A.

1 голос
/ 26 апреля 2011

Было бы поверхностно скопировать часть "A" объекта obj2.

Это нормально с точки зрения языка.

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

0 голосов
/ 26 апреля 2011
A::operator=(const A& value);

будет выполнено.obj1 неявно приведено (static_cast) к const A&.

Таким образом, ваше obj=obj1; эквивалентно

obj = static_cast<const A&>(obj1);

Очевидно, что неявно сгенерированное назначение будет назначать каждый нестатический член A.

Чтобы отрицать это, используйте частное / защищенное наследование.Используя публичное наследование, вы заявляете, что все объекты типа B могут на законных основаниях использоваться как объекты типа A.

Вы также можете явно объявить

A& A::operator=( const B& value );

Или вытакже может определять

A& A::operator=( const A& value );

, чтобы вести себя полиморфно.

0 голосов
/ 26 апреля 2011

перегрузит ваш оператор присваивания. и в дополнении B часть th будет назначена в части A ... ошибка компилятора не будет сгенерирована, пока вы не попытаетесь присвоить значения B, существующие в A

...