簡體   English   中英

基類中運算符重載的問題

[英]trouble with operator overloading in baseclass

嗨,我在繼承和運算符重載方面遇到了麻煩,希望你們能給我一些清晰度。

我有以下課程:

template<typename Type>
class Predicate{
public:
    Predicate() {};
    virtual ~Predicate(){};
    virtual bool operator()(const Type & value) = 0;
    virtual bool operator()(const Type * value){ //<-- this is the operator thats not working
        return (*this)(*value);
    };
};

template<typename Type>
class Always : public Predicate<Type>{
public:
    bool operator()(const Type & value){return true;}
    ~Always(){};
};

現在,我希望所有謂詞都接受引用和指針,但是當我在以下類中測試類時:

int main(){
    Always<int> a;
    int i = 1000;
    a(&i);
    system("pause");
    return 1;
}

我收到以下錯誤:

test.cpp: In function 'int main()':
test.cpp:10:6: error: invalid conversion from 'int*' to 'int' [-fpermissive]
  a(&i);
      ^
In file included from test.cpp:2:0:
predicates.h:22:7: error:   initializing argument 1 of 'bool Always<Type>::operator()(const Type&) [with Type = int]' [-fpermissive]
  bool operator()(const Type & value){return true;}

這是因為在聲明時:

bool operator()(const Type & value){return true;}

在子類中,您要隱藏 / 隱藏超類中運算符的任何其他重載。

如果添加:

using Predicate<Type>::operator();

現場演示

在子類中,一切正常。


從側面講,我認為同時允許const&const*是一種設計味道。 您應該只允許const&版本,並允許類的用戶執行*ptr如果他們具有ptr指針)。

模板和運算符重載掩蓋了這里的實際問題。 看一下產生相同錯誤的這段小代碼:

void f(int &);

int main()
{
  int *ptr;
  f(ptr);
}

編譯器不會讓你通過凡在預期的指針。 這就是您嘗試對派生類進行的操作。 當你對一個具體的操作Always ,的基本版本operator()不考慮。

查看當您對基類的指針(或引用)進行操作時,情況如何變化:

int main(){
    Predicate<int> *ptr = new Always<int>;
    int i = 1000;
    (*ptr)(&i);
    delete ptr;
}

編譯良好,因為現在考慮將基類運算符用於重載解析。 但這只是為了使您更好地理解問題。 解決方案是應用的非虛擬接口成語 使您的操作員不是虛擬的,並根據私有虛擬功能實施它們:

template<typename Type>
class Predicate{
public:
    Predicate() {};
    virtual ~Predicate(){};
    bool operator()(const Type & value) { return operatorImpl(value); }
    bool operator()(const Type * value) { return operatorImpl(value); }

private:
    virtual bool operatorImpl(const Type & value) = 0;
    virtual bool operatorImpl(const Type * value) {
        return (*this)(*value);
    }
};

template<typename Type>
class Always : public Predicate<Type>{
public:
    ~Always(){};
private:
    bool operatorImpl(const Type & value){return true;}
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM