2010-08-03 21 views
1

我正在寫兩個C++/CLI程序集。一個程序集有一個內部虛擬方法的基類。另一個程序集標記爲朋友幷包含派生類。奇怪的行爲與C++/CLI和朋友程序集

當我嘗試重寫內部虛擬方法時,編譯器迫使我將可見性級別更改爲public。

這是怎麼回事?爲什麼我必須這樣做?

代碼:

// Assembly 1 "FriendAssemblyBase" 
namespace FriendAssemblyTest 
{ 
    public ref class BaseClass 
    { 
    internal: 
     BaseClass() 
     { 
     } 

     virtual void DoSomething() 
     { 
     } 
    }; 
} 

// Allow "FriendAsseblyDerived" to see internals 
[assembly: ::System::Runtime::CompilerServices::InternalsVisibleToAttribute(
"FriendAssemblyDerived, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a95fe809ecc53c3a826aa32e3ab1309f2ecae4b91dc649457d704e150f3a4007a151ffe28852f947803dd1a1586c5c0ae2c9688bd76299857ee65ff7efb14905e03b33664a42e2fa1074080c3bad971623514ab6dd9fc4e4343ba7fb98884ecce45f96b71e5f1b55de88e36483274aa71c740fdfb14aacaada6ca22cb39bf9a2")]; 

// ---------------- 
// Assembly 2. "FriendAssemblyDerived". Strongly named and signed 
#using "FriendAssemblyBase.dll" as_friend 
namespace FriendAssemblyTest 
{ 

    public ref class Derived : BaseClass 
    { 
    public: 
     Derived() {} 

     void Foo() 
     { 
      DoSomething(); 
     } 

    internal: // <-- Causes C3252 (cannot reduce visibility of virtuals) 
     virtual void DoSomething() override 
     { 
     } 
    }; 
} 
+0

你能否提供一對虛擬類來演示你的類如何派生/包含另一個類? – sleepynate 2010-08-03 14:53:39

+0

我添加了一些代碼來說明。 – 2010-08-03 16:39:14

+0

「發佈屬性聲明」的哪一部分不清楚?再見。 – 2010-08-03 16:52:46

回答

0

因爲其他類FriendAssemblyBase可以調用BaseClass.DoSomething

Liskov替代原則說任何可以用基類完成的任何事情都必須適用於每個派生類。 DerivedClass.DoSomething必須對FriendAssemblyBase可見。可能發生的唯一方法是public:

+0

但它不能只是調用自己的虛擬功能?這與保護可見度有何不同? – 2010-08-04 04:35:41

+0

**'FriendAssemblyBase'中的其他**類,不一定是'BaseClass'本身,可以調用該函數。受保護的情況並非如此。 – 2010-08-04 12:23:17

+0

明白了。說得通。 – 2010-08-04 13:30:02