2017-10-23 6 views
0

基本クラスと派生クラスのfriend関数を使って以下のように '+'演算子をオーバーロードしました。を使用して派生クラスオブジェクトのベース部分にアクセスする方法。演算子

#include <iostream> 

using namespace std; 

class base 
{ 
    private: 
     int x; 

    public: 
     base(int a) : x(a) 
     { 
     } 

     void printx() 
     { 
      cout << "x : " << x << endl; 
     } 

     friend void operator+(int data, base &obj); 
}; 

void operator+(int data, base &obj) 
{ 
    cout << "in friend base" << endl; 
    obj.x = data + obj.x; 
} 

class derived : public base 
{ 
    private: 
     int y; 

    public: 
     derived(int a, int b) : base(a), y(b) 
     { 
     } 

     void printy() 
     { 
      cout << "y : " << y << endl; 
     } 

     friend void operator+(int data, derived &obj); 
}; 

void operator+(int data, derived &obj) 
{ 
    cout << "in friend derived" << endl; 

    operator+(data, obj.base); 
    obj.y = data + obj.y; 
    cout << "y in friend : " << obj.y << endl; 
} 

int main() 
{ 
    derived c(2, 3); 

    4 + c; 

    c.printx(); 
    c.printy(); 
} 

しかし、以下のプログラムが正常にコンパイルなっているが、これは

inoverload+.cpp: In function ‘void operator+(int, derived&)’: 
inoverload+.cpp:51:25: error: invalid use of ‘base::base’ 
    operator+(data, obj.base); 

以下のようにコンパイルエラーを与えています。

#include <iostream> 

using namespace std; 

class base 
{ 
    public: 
     int x; 

     base(int a) : x(a) 
     { 
     } 
}; 

class d1 : public base 
{ 
    public: 
     d1(int a) : base(a) 
     { 
     } 
}; 

class d2 : public base 
{ 
    public: 
     d2(int a) : base(a) 
     { 
     } 
}; 

class derived : public d1, public d2 
{ 
    public: 
     derived(int a) : d1(a), d2(a) 
     { 
     } 
}; 

int main() 
{ 
    derived obj(2); 

    cout << obj.d1::x << endl; 
} 

私は同じプログラムで同じことを行うことが可能だとして、最初のプログラムでは、派生クラスのオブジェクトを使用してベース部分にアクセスすることができなかった理由いずれかを説明していただけます。

注:私は既にキャストで試してみました。しかし、私の質問は、obj.baseを使ってベースにアクセスするのが正しくない場合です。これは、2番目のプログラムobj.d1 :: xでどのように正しいのでしょうか?

答えて

4

ドットオペレーターはメンバーアクセスです。しかし、derivedにはbaseのメンバーが存在しないので、obj.baseは不正です。

operator+(data, static_cast<base&>(obj)); 

メンバーd1にアクセスしないobj.d1::x第二のプログラムで:派生オブジェクトから明示的に基底クラス参照を取得するには、キャストする必要があります。メンバーxにアクセスします。しかし、あいまいさを解決するために、C++ではスコープ解決演算子を使用して、このメンバーが見つかった一意の基本クラスのサブオブジェクトを明確にすることができます。

+0

実際には、引数オブジェクトを変更しています。 – Knoep

+0

@Knoep - あ、そうです。トンネルビジョン – StoryTeller

+0

私は言及を忘れた。私はすでにキャストで試して、それは働いた。私の質問は、obj.baseが2番目のプログラムでなぜobj.d1を作成していないのかどうかです。 – kadina

2

operator+(data, obj.base);は、objにはbaseという名前のメンバーが含まれていることを示しますが、これは真ではありません。派生オブジェクトの基底部分はメンバとして表されません。

あなたのオブジェクトを基本型のように考えるためにオーバーロードを強制するには、それを基底クラスの参照にすることができます。コンパイラは、型が厳密にその関数呼び出しの基本型であるかのように扱わなければなりません。以下を試してください:

void operator+(int data, derived &obj) 
{ 
    cout << "in friend derived" << endl; 

    operator+(data, static_cast<base&>(obj)); // Cast happens here 
    obj.y = data + obj.y; 
    cout << "y in friend : " << obj.y << endl; 
} 
関連する問題