2017-12-12 10 views
3

私はinit(int* iNumber)関数を呼び出す必要があります。これは基本クラスから派生したものです。C++オーバーライド機能同じベーステンプレートクラスから多重継承を使用して曖昧な関数呼び出し

BaseClass.h

#pragma once 
#include "stdafx.h" 
template <class T> 
class BaseClass 
{ 
public: 
    BaseClass() {} 
    virtual ~BaseClass() {} 
    virtual void init(T* object) = 0; 
}; 

ChildClass.h

#pragma once 
#include "BaseClass.h" 

class ChildClass : public BaseClass<int>, public BaseClass<float> 
{ 
public: 
    ChildClass() {} 
    virtual ~ChildClass() {} 
}; 

ChildClassImpl.h

#pragma once 
#include "ChildClass.h" 
class ChildClassImpl : public ChildClass 
{ 
public: 
    ChildClassImpl(); 
    virtual ~ChildClassImpl(); 
private: 
    void init(int* iNumber) override; 
    void init(float* fNumber) override; 
}; 

ChildClassImpl.cpp

#include "stdafx.h" 
#include <iostream> 
#include "ChildClassImpl.h" 

ChildClassImpl::ChildClassImpl(){} 

ChildClassImpl::~ChildClassImpl(){} 

void ChildClassImpl::init(int* iNumber) 
{ 
    std::cout << "Integer constructor: " << *iNumber << std::endl; 
} 

void ChildClassImpl::init(float* fNumber) 
{ 
    std::cout << "Float constructor: " << *fNumber << std::endl; 
} 

MainClass

#include "stdafx.h" 
#include <iostream> 
#include "ChildClassImpl.h" 

using namespace std; 

int main() 
{ 
    ChildClass* childClass = new ChildClassImpl(); 
    int x = 10; 
    childClass->init(&x); 
    cout << "Test" << endl; 
    getchar(); 
    return 0; 
} 

コンパイル時にこれがあると、エラーに

Severity Code Description Project File Line Error 
(active)  "BaseClass<T>::init [with T=int]" is 
ambiguous ConsoleApplication4 d:\Learning\ConsoleApplication4\ConsoleApplication4\ConsoleApplication4.cpp 14 

を与える私はここで間違って何をしているのですか?私はそれを最小限の変更でどのように修正できますか?

+3

入れ '::のinit; BaseClassのを使用して::のinit;' 'どこかChildClass'の宣言では –

+3

'ChildClassImpl :: init'関数から出力した出力は、それらの関数を持つべきではないことを示しています。代わりに、それらの機能を*実際の*コンストラクタに入れる必要があります。 –

+1

@ SPD:公正であるために、それは良いプログラムデザインの広告ではなく、その問題を示す小さな例です。 –

答えて

0

このコードは、オーバーロード解決とアクセス制御チェックの前に名前の参照を実行するため、失敗します。それは最初のステップはどのクラスにスコープinitが属しているかを判断することです。この場合、initBaseClass<int>::initまたはBaseClass<float>::initのいずれかを参照する可能性があるため、結果はあいまいになります。だから、名前の検索がinitChildClass::initを参照し、コンパイラは、解像度をオーバーロードに進みますことを決定します

class ChildClass : public BaseClass<int>, public BaseClass<float> 
{ 
public: using BaseClass<int>::init; 
public: using BaseClass<float>::init; 

:余分using宣言を導入することChildClassスコープにそれらの機能の両方をもたらすでしょう。

代わりにあなたが(間違いとして便利ではありません)キャストを実行することができます:BaseClassの を使用して

static_cast<BaseClass<int> *>(childClass)->init(&x); 
+0

あなたの決断と説明について@VTTありがとうございます。 –

関連する問題