C++ 为什么基类对象的私有成员仍然从派生对象分配?

C++ 为什么基类对象的私有成员仍然从派生对象分配?,c++,inheritance,C++,Inheritance,在下面的代码中,Circle是Point的公共继承,其中Point的私有成员x,y不可访问。但是,当将圆圈c指定给点p时,我发现p实际上可以得到x和y的正确值。为什么会这样 #include<iostream> using namespace std; class Point { public: Point(float x = 0, float y = 0); void display(); private: float x, y; }; Point::Poi

在下面的代码中,
Circle
Point
的公共继承,其中
Point
的私有成员
x
y
不可访问。但是,当将
圆圈c
指定给
点p
时,我发现
p
实际上可以得到
x
y
的正确值。为什么会这样

#include<iostream>
using namespace std;
class Point {
public: Point(float x = 0, float y = 0);
        void display();
private:
    float x, y;
};
Point::Point(float a, float b)
{
    x = a; y = b;
}
void Point::display() {
    cout << x <<'\t'<< y << endl;
}
class Circle :public Point
{
public: Circle(float x = 0, float y = 0, float r = 0);
private:
    float radius;
};
Circle::Circle(float a, float b, float r) :Point(a, b), radius(r) {}

int main()
{
    Circle c(10, 10, 15);
    Point p = c;
    p.display();
    return 0;
}
圆是从点派生的,因此在调用时,在上面的圆构造函数行中:

Point(a, b)

它使用传入的值a和b初始化基类点,构造函数将它们分配给x和y。

您无权访问变量
x
y
,因为它们是私有的。但您可以访问public方法
display()
display()
是类
Point
的公共方法,可以访问私有变量


换句话说,您可以调用方法
display()
,但不能直接访问私有变量
x
y

点p=c
对象强制转换为点,并调用点类的默认赋值运算符。默认赋值运算符将所有值(以及私有数据)复制到新对象


查看更多信息

您不能通过派生类访问私有成员,当您调用display()函数(属于Point类)时,它可以显示x和y。当您假定
点p=c
并调用
p.display()
时,它仍然调用指针类的方法。因为Circle可以看到她父母的display()方法。将display()方法设为私有,Circle无法调用它。

可以在
Circle
子对象内访问
成员

由于没有为
定义复制构造函数,因此复制
的行为如下:

Point(const Point& p) : x(p.x), y(p.y) {}
Circle::Circle(float a, float b, float r) :Point(a, b), radius(r) {}
由于
继承自
c
可以转换为
常量点&
,从而
点p=c
复制
c
子对象
这称为“对象切片”

(在一个无关的注释中,“圆是一种点”是一种奇怪的关系。)

在这一行

Point p = c;
您正在调用点的复制构造函数:

Point::Point(const Point& p)
因为您可以从派生类创建对基类的引用,所以您的代码相当于:

Point &ref = c;
Point p = ref;
现在
p
将包含
点的副本
圆的一部分

因为您在
Circle
构造函数中初始化了
Point
部分
Circle
对象,如下所示:

Point(const Point& p) : x(p.x), y(p.y) {}
Circle::Circle(float a, float b, float r) :Point(a, b), radius(r) {}

点(a,b)
构造函数被调用,它将使用参数
a
b
初始化
的一部分,因为每个圆都是一个点。关于getter和setter的读取可能重复。