Унаследованный член из абстрактного класса не может быть инициализирован унаследованным конструктором - PullRequest
5 голосов
/ 17 декабря 2010
class CarPart
{
public:
    CarPart(): name(""), price(0) {}
    virtual int getPrice() = 0;//{return price;}
protected:
    int price;
    string name;
};

class Tire: public CarPart
{
public:
    virtual int getPrice() {return price;}
    Tire(): CarPart(), name("Tire"), price(50)
    {}
};

Visual 2010 сообщает, что имя и цена не являются членами производного, но они наследуются (ошибка c2614). Что я делаю не так?

Ответы [ 4 ]

8 голосов
/ 17 декабря 2010

Вы не можете инициализировать участников, которые не являются непосредственными членами вашего класса.n не является непосредственным членом deriv, это непосредственный участник base.

Однако n доступен для deriv, поэтому вы всегда можете назначить его в конструкторе deriv, но вам действительно нужно инициализировать его в конструкторе base.

Кроме того, у вас не может быть virtual конструкторов.Вы хотели использовать virtual деструкторы?

class base
{
public:
    base() : n(0) {} // Are you sure you don't want this?
    virtual void show() = 0;
protected:
    int n;
};

class deriv : public base
{
public:
    deriv() 
    {
        n = 0;
    }

    virtual void show() {}
};

РЕДАКТИРОВАТЬ (ответ на редактирование ОП): Для этого вам не нужны виртуальные методы:

class CarPart
{
public:
    CarPart(const char* newName, int newPrice) : name(newName), price(newPrice) {}

    const std::string& GetName() const { return name; }
    int GetPrice() const               { return price; }
private:
    std::string name;
    int price;
};

class Tire : public CarPart
{
public:
    Tire() : CarPart("Tire", 50) {}
};

Предполагая, что все ваши CarPart s должны иметь имя и цену, этого должно быть более чем достаточно.

2 голосов
/ 17 декабря 2010

1) n неинициализировано в базе;

2) virtual deriv(): n(0) {} не является конструктором

Вы, вероятно, хотели:

class base
{
public:
   base(int n) : n(n) {}

...

class deriv: public base
{
public:
deriv(): base(0) {}
...
1 голос
/ 17 декабря 2010

Обратите внимание, что конструкторы не могут быть виртуальными!

Вы не можете инициализировать члены базового класса, используя синтаксис инициализации членов.Или инициализируйте n в базовом классе (что является правильным способом сделать это):

class base 
{ 
public: 
    base(int n_ = 0) : n(n_) {}
    virtual void show() = 0;  
protected: 
    int n; 
}; 

class deriv: public base 
{ 
public: 
    deriv() : base(0) {} 
    void show() {} 
}; 

или присвойте значение n внутри конструктора производного класса (по крайней мере, плохо)не без инициализации в базовом классе:

class base 
{ 
public: 
    base(int n_ = 0) : n(n_) {}
    virtual void show() = 0;  
protected: 
    int n; 
}; 

class deriv: public base 
{ 
public: 
    deriv() { n = 1; } 
    void show() {} 
}; 
0 голосов
/ 17 декабря 2010

Вы не можете инициализировать член базового класса в производном классе, поскольку базовый класс уже создан до инициализации производного класса.Вы могли бы предоставить конструктор, который принимает параметр для значения n:

base(int val) : n(val) {}

Затем делегируйте его в ваш deriv конструктор:

deriv() : base(0) {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...