Помогите разобраться с буржуйским код стайлом
От: Аноним  
Дата: 07.06.08 12:25
Оценка:

The "slicing" of objects shall be avoided.

Explanation:

When an instance of a derived class is assigned or copied to an instance of its base class, any properties and methods of the derived class are dropped or "sliced". The remaining members of object may be in a state that, while consistent for the child, is no longer consistent with the parent. This may lead to unpredictable behavior or incorrect logic operations.

Example:

Improper Usage

class Base {
public:
       virtual void Print() { cout << "Base" << endl; };
};

class Derived : public Base {
public:
       void Print() { cout << "Derived" << endl; };
};

void PrintObject(Base obj)
{
     obj.Print();
}

...
    Derived obj;
    
    PrintObject(obj); //object slicing!!!
...


Proper Usage
class Base {
public:
       virtual void Print() { cout << "Base" << endl; };
};

class Derived : public Base {
public:
       void Print() { cout << "Derived" << endl; };
};

void PrintObject(Base& obj)
{
     obj.Print();
}

...
    Derived obj;

    PrintObject(obj); //now all is ok, reference is argument
...

Непонятно что за "slicing" properties мне казалось такого не может быть в C++. И как здесь спасет ссылка на базовый класс.
Добавлено форматирование, убран двойной интервал — Кодт
Re: Помогите разобраться с буржуйским код стайлом
От: Daevaorn Россия  
Дата: 07.06.08 12:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>The "slicing" of objects shall be avoided.

А>Непонятно что за "slicing" properties мне казалось такого не может быть в C++. И как здесь спасет ссылка на базовый класс.

Срезка объекта. Распространенный случай.
http://www.cs.ualberta.ca/~hoover/Courses/201/201-New-Notes/lectures/section/slice.htm
Re: Помогите разобраться с буржуйским код стайлом
От: Roman Odaisky Украина  
Дата: 07.06.08 12:51
Оценка:
Здравствуйте, Аноним, Вы писали:

А>The "slicing" of objects shall be avoided.

А>Непонятно что за "slicing" properties мне казалось такого не может быть в C++. И как здесь спасет ссылка на базовый класс.

struct Base
{
    virtual void hello() { std::cout << "Hi! I’m Base!" << std::endl; }
};

struct Derived: Base
{
    int x;
    void hello() { std::cout << "Hi! I’m Derived! My x equals " << x << "!" << std::endl; }
};

Derived d;
Base  bv = d;
Base& br = d;

d.hello();
bv.hello();
br.hello();

Как думаешь, что получится?

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

А дальше в гугл.
До последнего не верил в пирамиду Лебедева.
Re: Помогите разобраться с буржуйским код стайлом
От: Vain Россия google.ru
Дата: 09.06.08 10:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>void PrintObject(Base& obj)

А>И как здесь спасет ссылка на базовый класс.
Так что объект не будет пересоздаваться, а будет "приходить в функцию" уже созданным.
Можно бы было ещё const Base& сделать, если не надо его менять, но это приводить к вызову конструктора преобразования, если он есть. Что-бы этого избежать, я делаю где-то так (это уже было, в поиск).
class ExplicitType {
public:
  //error C2718: actual parameter with __declspec(align('#')) won't be aligned
  //ExplicitType(...) {}
  template<class T>
  ExplicitType(const T&) {}
};
void PrintObject(const Base& obj);
void PrintObject(ExplicitType obj);

Это приводит к "ambiguous call to overloaded function" если в PrintObject передаётся не объект класса из иерархии Base.
Т.е. что-то вроде этого получается:
void PrintObject(explicit const Base& obj); //fake
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.