2015-12-16 6 views
0

Я пытаюсь понять наследование до рукоятки в ООП. Итак, я использовал некоторые попытки. Но, два момента, я застрял, что один из них - object slicing. Другой вызывает порядок деструкторов. Почему Box {carton} необходимо для правильной копии ctor? Если добавлено Box {carton}, как можно преобразовать тип коробки в тип Box (я его абсолютно не понимаю).автоматическое наследование цепочки ссылок

// right ctor 
/* 
Carton(const Carton& carton) : Box {carton}, material {carton.material} 
{ std::cout << "Carton copy constructor" << std::endl; } 
*/ 

Код:

#include <iomanip> 
#include <iostream> 
#include <string> 
using namespace std; 

class Box 
{ 
protected: 
    double length; 
    double width; 
    double height; 
public: 
    // Constructors 
    Box(double lv, double wv, double hv); 

    Box(double side) : Box {side, side, side} 
    { std::cout << "Box(double) called.\n"; } 

    Box() { std::cout << "Box() called.\n"; } 

    double volume() const 
    { return length * width * height; } 

    double getLength() const { return length; } 
    double getWidth() const { return width; } 
    double getHeight() const { return height; } 
    ~Box() 
    { cout << "box destructor" << endl; } 

    void print(); 

    // copy ctor 
    Box(const Box& box) : length{box.length}, width{box.width}, height{box.height} 
    { std::cout << "Box copy constructor" << std::endl; } 
}; 


class Carton : public Box 
{ 
private: 
    string material {"Cardboard"}; 
public: 
    Carton(double lv, double wv, double hv, const string desc) : Box {lv, wv, hv}, material {desc} 
    { std::cout << "Carton(double,double,double,string) called.\n";} 

    Carton(const string desc) : material {desc} 
    { std::cout << "Carton(string) called.\n";} 

    Carton(double side, const string desc) : Box::Box(side),material {desc} 
    { std::cout << "Carton(double,string) called.\n";} 

    Carton() { std::cout << "Carton() called.\n";} 

    ~Carton() 
    { cout << "cartoon destructor" << endl; } 

    void print(); 

    // right ctor 
    /* 
    Carton(const Carton& carton) : Box {carton}, material {carton.material} 
    { std::cout << "Carton copy constructor" << std::endl; } 
    */ 

    Carton(const Carton& carton) : material {carton.material} 
    { std::cout << "Carton copy constructor" << std::endl; } 

}; 

int main() 
{ 
    // Declare and initialize a Carton object 
    Carton carton(20.0, 30.0, 40.0, "Glassine board"); 
    Carton cartonCopy(carton);    // Use copy constructor 
} 

// Ctor 
Box::Box(double lv, double wv, double hv) : length {lv}, width {wv}, height {hv} 
{ std::cout << "Box(double, double, double) called.\n"; } 

// Redefinitions 
void Box::print() 
{ 
    cout << "Box printttttt" << endl; 
} 
void Carton::print() 
{ 
    cout << "Carton printttttt" << endl; 
} 

ответ

0

Помните, что наследование является "является" отношения. A CartonявляетсяBox, поэтому вы можете использовать Carton, когда ожидается Box.

Однако будьте осторожны с проблемой object slicing. Если функция принимает аргумент Box по значению, и вы передаете объект Carton, функция получит только часть Box.


Кроме того, у вас есть еще одна проблема, в том, что ваша print функция не является virtual. Это означает, что даже если у вас есть указатель или ссылка на Box и передать Carton, функция Carton::print не будет вызываться.

Позволяет проиллюстрировать это на примере:

void foo(Box const& box) 
{ 
    box.print(); 
} 

int main() 
{ 
    Carton carton(...); 
    foo(carton); 
} 

Приведенный выше пример кода не будет иметь никаких проблем объектно-срезов, так как функция foo получает ссылку на базовый класс. Тем не менее, он будет печатать

 
Box printttttt 

Если вы Box::print виртуальный

virtual void print(); 

Тогда приведенный выше код будет печатать

 
Carton printttttt 
+0

спасибо за вашу помощь. Но как может компилятор передать 'carton' как type' Box & '? Я не понимаю этого. – askque

+0

@askque Прочтите первый раздел моего ответа еще раз. –

+0

okey, но почему бы не по значению (Box), а не по ссылке (Box &)? – askque

Смежные вопросы