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

Does the code get copied to derived class?

本文关键字:派生 复制 是否 代码      更新时间:2023-10-16

每当我从基类派生一个新类时,比如:

#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的实例时,我发现它在不同的地址有自己的变量,并且它也有一个成员函数。如果没有复制,它怎么能有自己的复制成员?

这就是我们在继承中对代码重用的意思吗?

编辑:

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

在继承过程中从不复制代码。但是,当在运行时创建或实例化子对象(类B)时,它继承了父类/对象(类A)的功能和属性。

类A的代码不会复制到类B,因为代码只有一个编写位置。

然而,这里锥的可重用部分,当使用类b时,u可以调用方法并使用成员,相对于privatepublic、etd,因此不必为做相同事情的两个类编写相同的代码

例如,如果我有一个圆和一个正方形,它们都有一个名为color的成员,我想要一个改变它的方法,我不需要写两次方法和成员,而是让它们继承将实现它一次的类Shape,然后它们都可以使用该方法,从而在两个位置重用一个方法

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

此外,从对话中的评论:

没有。没有什么是"复制"的,A和B的每个实例都有自己的变量值,除了任何静态数据成员。对于静态数据成员,同样没有进行复制;仅存在一个变量并且该变量由CCD_ 11和CCD_。

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

对于类的字段是否被复制到派生类中,也许更好的测试是:

#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中的内容相同。请注意,也可以在派生类中重新定义类成员,但如果我们将派生类的实例强制到父类,则原始成员仍然可用(就像我在示例中所做的那样)。

C++语言标准的

§1.8(2)定义了子对象的含义:

对象可以包含其他对象,称为子对象。子对象可以是成员子对象(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

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

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

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

我不认为我们使用继承来实现代码重用。