簡體   English   中英

編譯時檢查基類是否為“接口”

[英]Compile time check whether a base class is “interface”

事實證明,我原本想要的可能不可能不涉及C ++ 11我想稍微改變一下要求並問你是否可以實現這一點。

上一個問題

基本上我想在一個類繼承自“interface”時檢查編譯時間。 通過接口我的意思是僅使用純虛方法的類。 我想做以下代碼:

template <typename T>
class Impl : public T {
public:
STATIC_ASSERT_INTERFACE(T);
};

這里的行為是,如果T只有純虛方法,那么它將編譯,如果其中一個方法不是那么失敗。

任何人都可以想到這樣的事情嗎?

這基本上類似於Java接口 在C ++中,不存在interface本身,它只是一個用於具有所有純虛方法和僅static const數據成員的class的術語。

另外,純虛方法可能有也可能沒有函數體。 因此,C ++純虛方法與Java的抽象方法不完全相同。

不幸的是,你所要求的是不可能在C ++中進行模擬。

首先,接口並不是C ++的本機概念。 我敢肯定大多數程序員都知道它們是什么,但是編譯器不知道,而這就是你遇到問題的地方。 C ++可以做很多事情,我打賭你可以把它變成很多不同的語言,但是如果你要寫C ++,最好用C ++的方式做。

另一件事 - 這里有很多灰色區域。 如果你有一個像你建議的“界面”怎么辦,但有人做過其中一個:

// Technically not a member function, but still changes the behavior of that class.
bool operator==(const Interface &left, const Interface &right);

我幾乎100%肯定你不能阻止某人這樣做。

你或許可以確保沒有成員變量,即使我不確定我是否同意這種做法。 創建一個空類,然后執行static_assert(sizeof(InterfaceClass) == sizeof(Empty)) 我不確定假設大小為0是否安全 - 這對於更熟悉標准的人來說是一個問題。

你想要的不能直接完成,正如其他人已經解釋過的那樣。

但是,您仍然可以通過界面開發人員的一些紀律來獲得所需的行為。 如果所有接口都派生自公共基類Interface ,則可以使用類似於此問題的技術在編譯時檢查Interface是否為基類。

例如 :

class Interface {
    public :
        virtual ~Interface() { }
};

template <typename T>
struct IsDerivedFromInterface {
    static T t();
    static char check(const Interface&);
    static char (&check(...))[2];
    enum { valid = (sizeof(check(t())) == 1) };
};

class MyInterface : public Interface {
    public :
        virtual void foo() = 0;
};

class MyBase {
    public :
        virtual void bar() { }
};

class Foo : public MyInterface {
    public :
        virtual void foo() { }
};
BOOST_STATIC_ASSERT(IsDerivedFromInterface<Foo>::valid);    // just fine

class Bar : public MyBase {
    public :
        virtual void bar() { }
};
BOOST_STATIC_ASSERT(IsDerivedFromInterface<Bar>::valid);    // oops

當然,即使基類不是接口,基類的開發人員也可以欺騙並從Interface派生。 這就是為什么我說它需要開發人員的一些紀律。

盡管如此,我看不出這將如何有用。 我從來沒有覺得我需要這種編譯時檢查。

暫無
暫無

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

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