我在進行iKM測試時遇到了一個問題。有一個基類具有兩個帶私有訪問說明符的抽象方法。有一個派生類覆蓋了這些抽象方法,但使用了protected/public訪問說明符。覆蓋差異訪問規範C++
我從來沒有遇到這樣的事情,派生類中的重寫方法有不同的訪問規範。這是否允許?如果是,它是否符合基礎與派生(即安全可替代)之間的「是」關係。
你能指點我一些可以提供關於類的這些用法的更多細節的參考嗎?
謝謝。
我在進行iKM測試時遇到了一個問題。有一個基類具有兩個帶私有訪問說明符的抽象方法。有一個派生類覆蓋了這些抽象方法,但使用了protected/public訪問說明符。覆蓋差異訪問規範C++
我從來沒有遇到這樣的事情,派生類中的重寫方法有不同的訪問規範。這是否允許?如果是,它是否符合基礎與派生(即安全可替代)之間的「是」關係。
你能指點我一些可以提供關於類的這些用法的更多細節的參考嗎?
謝謝。
許多人指出這是合法的。
但是,「IS-A」部分並不那麼簡單。當涉及到「動態多態性」,「IS-A」關係成立時,也就是說,你可以用超級你做的所有事情,你也可以使用派生實例。然而,在C++中,我們也有一些經常被稱爲靜態多態(靜態多態的模板,大部分時間)。請看下面的例子:
class A {
public:
virtual int m() {
return 1;
}
};
class B : public A {
private:
virtual int m() {
return 2;
}
};
template<typename T>
int fun(T* obj) {
return obj->m();
}
現在,當您嘗試使用 「動態多態性」 一切似乎是確定:
A* a = new A();
B* b = new B();
// dynamic polymorphism
std::cout << a->m(); // ok
std::cout << dynamic_cast<A*>(b)->m(); // ok - B instance conforms A interface
// std::cout << b->m(); fails to compile due to overriden visibility - expected since technically does not violate IS-A relationship
...但是當你使用「靜態多態」,你可以說,「是一個」關係不再成立:
A* a = new A();
B* b = new B();
// static polymorphism
std::cout << fun(a); // ok
//std::cout << fun(b); // fails to compile - B instance does not conform A interface at compile time
那麼,到底,不斷變化的方法知名度「而合法」但是這是醜陋的一個C++中的東西可能會導致您陷入陷阱。
是的,只要簽名是相同的,這是允許的。 在我看來,是的,你是對的,覆蓋可見性(例如,公共 - >私人)打破IS-A。我相信斯科特·邁爾斯有效的C++系列對此進行了討論。
允許在兩個方向上(即從private
到public
和從public
到private
)。
另一方面,我認爲它不會打破IS-A關係。我基地我的論點2個事實:
Base&
(或Base*
)處理,你有完全一樣的界面和以前public
和調用private
方法直接反正:更多的打字有同樣的效果,這是合法的,可訪問靜態(非動態)檢查:
class A {
public:
virtual void foo() = 0;
private:
virtual void bar() = 0;
};
class B : public A {
private:
virtual void foo() {} // public in base, private in derived
public:
virtual void bar() {} // private in base, public in derived
};
void f(A& a, B& b)
{
a.foo(); // ok
b.foo(); // error: B::foo is private
a.bar(); // error: A::bar is private
b.bar(); // ok (B::bar is public, even though A::bar is private)
}
int main()
{
B b;
f(b, b);
}
現在,你爲什麼要這麼做?如果直接使用派生類B
(第二參數f()
)而不是通過基礎A
接口(f()
的第一參數),那麼這很重要。 如果您總是使用摘要A
界面(正如我一般推薦的那樣),它仍然符合「IS-A」關係。
謝謝你將檢查你指出的參考。謝謝。 – irappa
我不認爲它打破* is-a *,但沒有購買我不知道的書。根據某些人,Scott Meyers可能是[5個最重要的C++人員之一](http://www.artima.com/cppsource/top_cpp_people.html),但他幾乎沒有在線存在。 –