代码是否被复制到派生类?

时间:2014-11-06 13:59:50

标签: c++ inheritance code-reuse

每当我从基类派生一个新类时说:

#include <iostream>

class A {

protected:
     int f;

public:

    void get() {
        std::cout << "The address is: "
        << &f << std::endl;
        }
};

class B : public A {
        // ....
};

int main() {

     A a;
     a.get();

     B b;
     b.get();

     return 0;
}
  

地址是:0xbfb0d5b8
  地址是:0xbfb0d5bc

这是否意味着class A中的所有代码都会被复制到class B?因为我在类B中没有任何内容,即没有数据成员或函数所以,当我创建一个B类实例时,我发现它在不同的地址有自己的变量,并且它还有一个成员函数。如果它们没有复制,它如何拥有自己的复制成员?

继承中的代码重用是什么意思?

编辑:

更新了我的代码以反映复制变量的含义。

6 个答案:

答案 0 :(得分:2)

继承期间永远不会复制代码。但是,当在运行时创建或实例化子对象(类B)时,它继承父类/对象(类A)的功能和属性。

答案 1 :(得分:1)

我不确定“复制”是否正确(编译器只会编译class A中的代码一次)。由于您使用了公共继承,class B实际上 是一种特殊类型的class A。因此,class B可以访问class A的每个(非私有)成员,因此代码会被重复使用。

另外,从评论中的对话:

没有。没有任何东西被“复制”,A和B的每个实例都有自己的变量值,除了任何静态数据成员。对于静态数据成员,再次没有复制;只有一个变量,并且由AB的所有实例共享。

答案 2 :(得分:1)

来自A类的代码不会复制到B类,因为只有一个代码被写入。

然而,这里有可重用部分,当使用类bu时可以调用该方法并使用成员,相对于privatepublic,etd,因此不必编写相同的内容两个做同样事情的类的代码

例如,如果我有一个圆和一个正方形,并且它们都有一个名为color的成员,我想要一个改变它的方法,我不需要编写方法和成员两次,但让它们继承类Shape将实现它一次,然后他们都将能够使用该方法,从而在两个地方重用一个方法

答案 3 :(得分:1)

在您的示例中,您要比较两个不同类的两个不同实例。不同的实例意味着存储实例数据的不同基地址。

对于是否在派生类中复制类的字段的更好的测试可能如下:

#include <iostream>

class A {

protected:
 int f;

public:

void get() {
    std::cout << "The address is: " << &f << std::endl;
    }
};

class B : public A {
    // ....
};

int main() {

 B b;
 b.get();

 A *a = &b;
 a->get();

 return 0;
}

输出是:

The address is: 0x7fff41d523f0
The address is: 0x7fff41d523f0

使用该程序,我们可以看到即使我们有一个类B的实例,它的继承内容在物理上与原始类A中的内容相同。请注意,也可以在派生类中重新定义类成员,但如果我们将派生类的实例强制转换为父类,则原始成员仍然可用(正如我在我的示例中所做的那样)。

答案 4 :(得分:1)

§1.8(2)的C ++语言标准定义了子对象的含义:

  

对象可以包含其他对象,称为子对象。子对象可以是成员子对象(9.2),基类子对象(子句10)或数组元素。不是任何其他对象的子对象的对象称为完整对象

这些是您应该熟悉的成员子对象和数组元素的示例:

int a[5];
a[2]; // the third array element subobject of the complete object a

struct S { int x; }
S s;
s.x; // a member subobject of the complete object s

留下剩下的子对象,你感兴趣的对象:基类子对象。

struct B { int x; }
struct D : public B { int y; }

D d;
d.y; // a member subobject of the complete object d
d.x; // a member subobject of a base class subobject of the complete object d

B &b = d; // a reference to a base class subobject of the complete object d

派生类的每个实例都包含其基类的实例,作为基类子对象。

答案 5 :(得分:0)

我对继承和代码重用之间的关系也有一些疑问。这是我对此的看法。

继承是一种用于分类和促进多态性的机制。使用继承,我们可以构建在不同抽象级别的类别中分隔的概念层次结构。通过这样做,我们可以有效地使用另一个OOP概念,即多态,它允许相同的控制代码管理类别中的所有对象,即使它们的实现不同。

我不认为我们将继承用于代码重用目的。