C++继承,将成员添加到派生类并重新定义构造函数

Posted

技术标签:

【中文标题】C++继承,将成员添加到派生类并重新定义构造函数【英文标题】:C++ inheritance, add member to a derived class and redefine constructor 【发布时间】:2014-11-26 16:18:00 【问题描述】:

我对 C++ 有一个菜鸟问题。

我有一本课本:

class Book 
public:
    string name;
    Author author;
    double price;
    int qtyInStock;

public:
    Book(const string & name, 
         const Author & author, 
         double price, 
         int qtyInStock = 0);
    string getName() const;
    Author getAuthor() const;
    double getPrice() const;
    void setPrice(double price);
    int getQtyInStock() const;
    void setQtyInStock(int qtyInStock);
    void print() const;
    string getAuthorName() const;
;

使用构造函数:

Book::Book(
    const string & name, 
    const Author & author, 
    double price, 
    int qtyInStock)
: name(name), author(author) 
 // Init object reference in member initializer list
    // Call setters to validate price and qtyInStock
    setPrice(price);
    setQtyInStock(qtyInStock);

现在我想创建一个派生自它的新类“BookDigital”,如下所示:

class DigitalBook:public Book

public:
    string site;
    DigitalBook(const string & name, 
                const Author & author, 
                double price, 
                int qtyInStock = 0,
                string & site);
;

使用构造函数:

DigitalBook:DigitalBook(
    const string & name, 
    const Author & author, 
    double price, int qtyInStock,
    string & site)
: name(name), author(author)  // Init object reference in member initializer list
    // Call setters to validate price and qtyInStock
    setPrice(price);
    setQtyInStock(qtyInStock);

我为电子书添加了一个会员“网站”

当我编译这个时,它显示消息错误:

||=== Build: Debug in Test C++ (compiler: GNU GCC Compiler) ===|
C:\Users\aalovisi\Desktop\Test C++\Book.h|34|error: default argument missing for parameter 5 of 'DigitalBook::DigitalBook(const string&, const Author&, double, int, std::string&)'|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp|14|error: found ':' in nested-name-specifier, expected '::'|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp||In constructor 'DigitalBook::DigitalBook(const string&, const Author&, double, int, std::string&)':|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp|15|error: class 'DigitalBook' does not have any field named 'name'|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp|15|error: class 'DigitalBook' does not have any field named 'author'|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp|15|error: no matching function for call to 'Book::Book()'|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp|15|note: candidates are:|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp|7|note: Book::Book(const string&, const Author&, double, int)|
C:\Users\aalovisi\Desktop\Test C++\Book.cpp|7|note:   candidate expects 4 arguments, 0 provided|
C:\Users\aalovisi\Desktop\Test C++\Book.h|8|note: Book::Book(const Book&)|
C:\Users\aalovisi\Desktop\Test C++\Book.h|8|note:   candidate expects 1 argument, 0 provided|
||=== Build failed: 5 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

为什么?谢谢你的帮助

【问题讨论】:

您是否阅读了错误消息、评估了您遇到的错误并尝试纠正它们?第一个说“参数 5 缺少默认参数。” 如果您不知道该消息的含义,请尝试搜索它。例如,谷歌搜索“默认参数”会出现“learncpp.com/cpp-tutorial/77-default-parameters”,它解释了默认参数(或参数)是什么、它们如何工作、它们必须满足什么要求等。 【参考方案1】:
default argument missing for parameter 5

你有第四个参数的默认参数,但第五个没有。如果一个参数有一个默认参数,那么它后面的所有参数也必须如此。将qtyInStock 设为最后一个参数,删除其默认参数,或将默认参数提供给site

found ':' in nested-name-specifier, expected '::'

你写的是DigitalBook:DigitalBook而不是DigitalBook::DigitalBook

class 'DigitalBook' does not have any field named 'name'
class 'DigitalBook' does not have any field named 'author'

您只能在构造函数的初始化列表中初始化当前类的成员,而不是基类。不要尝试初始化每个基础成员,而是初始化整个基础子对象:

DigitalBook::DigitalBook(const string & name, const Author & author, double price, int qtyInStock, string & site)
    : Book(name, author, price, qtyInStock), site(site)

没有必要调用setPricesetQtyInStock,假设Book 构造函数对这些参数做了正确的事情。

no matching function for call to 'Book::Book()'

这是因为,因为您没有在初始化列表中包含Book 的条目,所以它需要被默认初始化;但它没有合适的构造函数。如上所述添加初始化程序也将解决此问题。

【讨论】:

【参考方案2】:

如果一个函数的某些参数有默认值,那么所有其他参数也应该有默认值。这就是编译器在第一条消息中试图告诉你的内容。

【讨论】:

【参考方案3】:

我认为您的问题是您为构造函数中的第四个参数定义了默认值(int qtyInStock = 0),但没有为第五个参数(字符串和站点)定义默认值。

您应该避免参数 4 的默认值或参数 5 的默认值。

我也认为你的构造函数有问题:我猜 DigitalBook::DigitalBook 应该调用基类构造函数

【讨论】:

【参考方案4】:

构建DigitalBook 对象意味着必须构建Book 对象。 但是,您没有 Book 的默认构造函数(没有参数)

因此,当您尝试创建您的 DigitalBook 时,无法构建父类,您会收到错误消息。

你应该做的是

DigitalBook:DigitalBook(const string & name,
                        const Author & author,
                        double price,
                        int qtyInStock,
                        string & _site) :
     Book(name, author, price, qtyInStock),
     site(_site)


这样,您可以在派生类的构造函数中指定如何构建它所依赖的固有类的对象

【讨论】:

【参考方案5】:

解决了这个问题,谢谢:)

class Person

public:
std::string m_strName;
int m_nAge;
bool m_bIsMale;

std::string GetName()  return m_strName; 
int GetAge()  return m_nAge; 
bool IsMale()  return m_bIsMale; 
void print() const;

Person(std::string strName = "", int nAge = 0, bool bIsMale = false)
    : m_strName(strName), m_nAge(nAge), m_bIsMale(bIsMale)


;

class BaseballPlayer : public Person

public:
double m_dBattingAverage;
int m_nHomeRuns;

BaseballPlayer(double dBattingAverage = 0.0, int nHomeRuns = 0)
   : m_dBattingAverage(dBattingAverage), m_nHomeRuns(nHomeRuns)


;

【讨论】:

以上是关于C++继承,将成员添加到派生类并重新定义构造函数的主要内容,如果未能解决你的问题,请参考以下文章

C++继承详解

C++入门派生类和基类的构造/析构函数关系

c++继承总结

C++ 面试题

C++基础6 继承 类型兼容 satatic 多继承 虚继承 多态 案例 虚析构函数 重载重写重定义

C++继承