C++构造函数的问题

eoi*_*nzy 37 c++ constructor

编辑:这个问题出现了,我想我已经开始了!去StackOverflow !! :d

我的考试即将开始,去年考试的一个问题是通过实施以下构造函数来发现问题,并编写一个更正的问题.

Rectangle::Rectangle(string col, int len, int br)
{
    setColour(col);
    length =len;
    breadth=br;
}
Run Code Online (Sandbox Code Playgroud)

类定义如下:

class Polygon
{
public:
    Polygon(string col="red");
    void printDetails(); // prints colour only
    virtual double getArea()=0;
    void setColour(string col);
private:
    string colour;
};


class Rectangle : public Polygon
{
public:
    Rectangle(string, int, int);
    void printDetails(); // prints colour and area
    // for part 3, delete the line below
    double getArea();
private:
    int length;
    int breadth;
};
Run Code Online (Sandbox Code Playgroud)

我已将代码写入编译器,运行正常.我猜这个问题与继承有关,因为它string colour;是私有的,但是setColour是公开的,所以我无法弄明白.除非它Rectangle::Rectangle(string col, int len, int br):length(len), breadth(br)然后在construcor或其他东西中设置颜色.

它只值3分,所以如果没有人想回答它就没什么大不了的,但我想如果我将有一个程序员的职业生涯,我尽可能多地了解它.;)

谢谢你的帮助.

PS,见getArea()Rectangle.当我删除它告诉我它"无法实例化抽象类".那是什么意思?

编辑:这是主要的:

void main (void)
{
    Rectangle rect1 ("blue",5,6);
    Rectangle *prect2 = new Rectangle("red",5,6);
    rect1.setColour("red");
    rect1.printDetails();
    prect2->printDetails();
}
Run Code Online (Sandbox Code Playgroud)

J T*_*J T 23

我没有看到任何错误,但你可以通过使用初始化列表使其更有效(否则你的两个类的私有成员初始化两次):

Rectangle::Rectangle(string col, int len, int br) 
: Polygon(col), length(len), breadth(br)
{

}
Run Code Online (Sandbox Code Playgroud)

请注意,初始化列表也可以调用Polygon的构造函数.

请参阅为什么我更喜欢使用成员初始化列表?有关使用初始化列表的优点的完整描述.

  • ...并且在两个构造函数中通过引用传递字符串将消除另外两个字符串构造. (6认同)

Lau*_*nis 10

如果它是关于最佳C++实践,那么:

  1. 通过const引用传递字符串参数;
  2. 使用初始化列表并通过将颜色传递给父构造函数而不是setColour来初始化颜色.

  • `通过const引用传递字符串参数`除非您正在获取字符串的副本...然后您应该通过值和复制交换或移动... (2认同)

rer*_*run 9

我唯一看到的是有两个printDetails(),但基类一个不是虚拟的,所以你不会得到预期的多态行为.

  • 我同意这一点.对我来说,这是唯一的"真实"问题. (3认同)

T.E*_*.D. 7

我看到的主要"问题"(它有点小)是派生的构造函数让父类使用其默认的colo(u)r值("red"),然后提供它自己的.这有点浪费,当你可以从一开始就给它正确的那个.

Rectangle::Rectangle(string col, int len, int br) : Polygon(col) {
    length =len;
    breadth=br;
};
Run Code Online (Sandbox Code Playgroud)

现在,完成上述操作后,您可以通过以下方式初始化所有成员:

Rectangle::Rectangle(string col, int len, int br) 
    : Polygon(col), length(len), breadth(br) {};
Run Code Online (Sandbox Code Playgroud)

嗯.现在我看看这个,还有另外一个问题.构造函数std::string通过复制传递对象,而不是修改它们.这也是一种浪费.所有构造函数string参数都应该更改为string const &参数.这可能会避免在运行时对字符串进行额外的复制构造,并通知编译器和用户您实际上并未修改输入字符串(这实际上并非如此).

所以最终版本看起来更像是:

Rectangle::Rectangle(string const & col, int len, int br) 
    : Polygon(col), length(len), breadth(br) {};
Run Code Online (Sandbox Code Playgroud)

std::string对于每个Rectangle被调用为2的构造函数,此公式将从4个构造(和3个析构)中获取.通过对Polygon构造函数进行相同的更改,可以进一步将其转换为1 .


Sto*_*net 6

您应该使用col参数调用基础构造函数:

Rectangle::Rectangle(string col, int len, int br) : Polygon(col)
{
    //setColour(col);
    length =len;
    breadth=br;
}
Run Code Online (Sandbox Code Playgroud)

关于getArea():
当你删除它时它不编译的原因是因为该函数在你的Polygon类中被标记为纯虚拟virtual double getArea()=0;使用=0;