2017-02-10 14 views
-3

に私はC++を使用して新しいプロジェクトを開発しています:仮想クラスや継承C++

ファイルをA.cpp

#ifndef A_hpp 
#define A_hpp 

class A{ 

public: 
    A(int at, int bt); 
    ~A(); 
    virtual double b()=0; 
    virtual double c()=0; 
    virtual double g()=0; 
private: 
    int at; 
    int bt; 
}; 

#endif /* A_hpp */ 

ファイルA.cpp

#include "A.hpp" 

A::A(int at, int bt){ 
    this->at=at; 
    this->bt=bt; 
} 

A::~A(){ 
    //no code 
} 

ファイルB.hpp

#ifndef B_hpp 
#define B_hpp 

#include "A.hpp" 
class B:public A{ 

public: 
    B(int at, int bt, double val); 
    ~B(); 

private: 
    double *elems; 
}; 
#endif /* B_hpp */ 

ファイルB.cpp

#include "B.hpp" 
#include "A.hpp" 

B::B(int at, int bt, double val):A(at, bt){ 

    elems=new double[at*bt]; 

    for(int i=0;i<at*bt;i++) 
     *(elems+i)=val; 
} 
B::~B(){ 
    delete []elems; 
} 

double A::c(){ 
     return *elem; 
    } 

double A::b(){ 
     return (*elem)-*(elem+1); 
    } 


double A::g(){ 
     return (*elem)*(*elem)*(*elem); 
    } 

I取得エラー、Iは、これらの仮想関数b()、C()らGを実装宣言されていない識別子 'ELEM'の使用()クラスBで

+3

コピー&ペーストしてくださいエラーメッセージを表示する代わりに、それを言い換えます。編集:インデントとスペースの欠如はあなたのコード**を非常に**読みにくいものにしました。 'A'クラス(' double A :: b() ')に対して' a'、 'b'、' c'関数を実装しています。 'A'クラスは' elems'について何も知りません。 'B'クラス(' double B :: b() ')のためにそれらを実装したいですか? –

+0

インデントしてください! –

+0

Aのメンバー関数 'b、c、g'を' B.cpp'のソースに定義するのはなぜですか? – Raindrop7

答えて

0

問題は、基本クラスvirtual関数のオーバーライドを実装していることですctly。

何あなたのコードは実際にあなたのベースクラスを考えるとB

からクラスのメンバ変数を使用しようとしているときにAから純粋仮想関数を実装してやっている:

class A 
{ 
public: 
    A(int at, int bt); 
    ~A(); 
    virtual double b()=0; 
    virtual double c()=0; 
    virtual double g()=0; 
private: 
    int at; 
    int bt; 
}; 

あなたの子クラスは次のようになります。そのようなBの実装と

class B:public A 
{ 
public: 
    B(int at, int bt, double val); 
    ~B(); 
    virtual double b(); 
    virtual double c(); 
    virtual double g(); 
private: 
    double *elem; 
}; 

B::B(int at, int bt, double val):A(at, bt) 
{ 
    elem=new double[at*bt]; 
    for(int i=0;i<at*bt;i++) 
    { 
     *(elem+i)=val; 
    } 
} 
double B::a() 
{ 
    return *elem; 
} 
B::~B() 
{ 
    delete []elem; 
} 
double B::b() 
{ 
    return (*elem)-*(elem+1); 
} 

double B::g() 
{ 
    return (*elem)*(*elem)*(*elem); 
} 
+0

これは 'elems'の代わりに' elem'の誤ったタイプミスであるという元の問題には対処していません。 – Gambit

+0

また、 'b、c、g'純粋仮想関数を作ることは、クラスB ADTを作るでしょう、したがってそれをインスタンス化することはできません。 – Raindrop7

+0

@ Raindrop7私の悪い、それはコピー貼りがスリップアップした。 –

0

タイプミスがあります。 elemelemsに変更してください。

プラス、

あなたはクラスBヘッダにメソッドを追加する必要が仮想inheritaceをimlementするには:

:.cppファイルに Bによって

virtual double b(); 
virtual double c(); 
virtual double g(); 

と実装の変更の名前空間A

double B::c(){ 
     return *elems; 
    } 
double B::b(){ 
     return (*elems)-*(elems+1); 
    } 
double B::g(){ 
     return (*elems)*(*elems)*(*elems); 
    } 
0

具体的にはB.cppファイルの実装を「クラスBに実装する」と誤解していると思います。 double A::c(){ ...と書くと、この実装を書くファイルに関係なく、AcクラスはBに実装されず、cクラスに実装されます。そしてクラスAは、Bのメンバであるelemsを認識していません。エラーメッセージUse of undeclared identifier 'elem'について説明しています。

double B::c(){ ...を代わりに書き出し、Bの定義にdouble c()と宣言します。(他の機能のためのコースの同じ。)

0

elemsは、あなたが親から子のメンバーにアクセスすることはできませんので、クラスAから派生したクラスBのメンバーである:

double A::b(){ 
    return (*elems)-*(elems+1); // elems is a member of B not A 
}