【问题标题】:c++ constructor and derived objectc++构造函数和派生对象
【发布时间】:2017-05-13 15:21:48
【问题描述】:

我得到了这段代码,想知道为什么在 Class Cylinder 中有一行

Cylinder(double r, double h) : base (r), height(h) {}

不是

Cylinder(double r, double h) : base.radius (r), height(h) {}

我的意思是一个 double 被移交并且 base 是一个 Cylinder,它不应该是 base.radius 吗?

// member initialization
#include <iostream>
using namespace std;

class Circle {
    double radius;
  public:
    Circle(double r) : radius(r) { }
    double area() {return radius*radius*3.14159265;}
};

class Cylinder {
    Circle base;
    double height;
  public:
    Cylinder(double r, double h) : base (r), height(h) {}
    double volume() {return base.area() * height;}
};

int main () {
  Cylinder foo (10,20);

  cout << "foo's volume: " << foo.volume() << '\n';
  return 0;
}

【问题讨论】:

  • 没有继承或派生对象?
  • 其实不用,因为需要调用基类的(唯一的)构造函数!
  • 您是否对base 的命名感到困惑?
  • 您在考虑 C# 中的 base 关键字吗?它在 C++ 中不存在。
  • 你为什么回滚我的编辑?如前所述,不涉及派生!再次投反对票,让您的问题再次不清楚。

标签: c++ class constructor


【解决方案1】:

我得到了这段代码,想知道为什么在 Class Cylinder 中有一行

Cylinder(double r, double h) : base (r), height(h) {} 

不是

Cylinder(double r, double h) : base.radius (r), height(h) {}

调用base.radius (r) 将不起作用,因为它是Circleprivate 成员。 即使它不是private,您也无法在初始化列表中的构造过程中访问它。
不过使用Circle 构造函数来初始化radius 完全没问题。

【讨论】:

  • 成为private 并不是唯一的原因。制作 radius protected 甚至 public 你会看到的。
  • @BoundaryImposition 是的,你是对的。我还提到了这一点(没有更好的措辞)。
【解决方案2】:

首先,您的代码中没有继承。其次,当您调用Cylinder 构造函数时,它的成员会被构造。由于Circle 没有默认构造函数,您必须确保在构造Cylinder 期间调用Circle 的构造函数。如果你有

Cylinder(double r, double h) : height(h) {}

编译器会抱怨缺少Circle 的默认构造函数,因为如果您不显式调用构造函数,Circle 将使用构造函数

Circle::Circle()

不存在(已删除,因为Circle 声明了不同的构造函数)。还有

Cylinder(double r, double h) : base.radius (r), height(h) {}

无法工作因为 radius 在 Circle 中是私有的,因为您只能在初始化列表中初始化 Cylinder 的成员(甚至不允许基类的成员)。

【讨论】:

  • 感谢这句话“第二,当你调用 Cylinder 构造函数时,它的成员就会被构造出来。”让我明白了:=)
【解决方案3】:

首先,这里的名字base非常非常糟糕;你的 Circle 对象不是基础!!

而且,不,一个类不能直接初始化其成员的成员(或真实基的成员)。那将是利益冲突、责任混淆、敏感性大火。

一个类提供了一个接口来管理它,这个接口由函数组成,而不是直接访问成员。如果您在不让Circle 知道的情况下进入并更改了它的数据,那将是多么令人困惑!

你用它的构造函数初始化一个对象,然后让构造函数做它认为正确的事情。在这种情况下,构造函数确实会按照您的意愿设置radius 成员。

了解black boxes

【讨论】:

  • 圆柱体的顶部和底部都有底座,因此得名。从几何 POV 来看,命名很好。
  • @πάνταῥεῖ:我明白了,但在 C++ 程序中这仍然是一个糟糕的选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-21
  • 2011-05-04
  • 2018-07-11
  • 2023-04-07
  • 1970-01-01
  • 2021-07-15
  • 2016-06-28
相关资源
最近更新 更多