473,408 Members | 2,888 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

VC++ 2005: private virtual functions

Something I don't get it:

Say we have:

ref class Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Base");}
public:
void SomeAccessibleFunction()
{SomeVirtualFunction();}
};

ref class Derived : public Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};

int main(array<System::String ^> ^args)
{
Base^ handle = gcnew Derived();
handle->SomeAccessibleFunction();

return 0;
}

I would expect to get "Derived" as the result, right? However, I get
"Base", and strange warnings during compilation:

".\PrivateVirtual.cpp(8) : warning C4486: 'Base::SomeVirtualFunction' :
a private virtual method of a ref class or value class should be marked
'sealed'
..\PrivateVirtual.cpp(16) : warning C4486:
'Derived::SomeVirtualFunction' : a private virtual method of a ref
class or value class should be marked 'sealed'
"

If I try explicit overriding:

..\PrivateVirtual.cpp(17) : error C3671: 'Derived::SomeVirtualFunction'
: function does not override 'Base::SomeVirtualFunction'
..\PrivateVirtual.cpp(16) : warning C4486:
'Derived::SomeVirtualFunction' : a private virtual method of a ref
class or value class should be marked 'sealed'

What is going on here?

Nov 17 '05 #1
20 2373
Hi Nemanja!
ref class Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Base");}
public:
void SomeAccessibleFunction()
{SomeVirtualFunction();}
};

ref class Derived : public Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};

int main(array<System::String ^> ^args)
{
Base^ handle = gcnew Derived();
handle->SomeAccessibleFunction();

return 0;
}

I would expect to get "Derived" as the result, right? However, I get
"Base", and strange warnings during compilation:

".\PrivateVirtual.cpp(8) : warning C4486: 'Base::SomeVirtualFunction' :
a private virtual method of a ref class or value class should be marked
'sealed'


"private" virtual functions are useless! because nobody can overwrite it!

You need to declare your virtual functions at least as "protected"!

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #2
> private" virtual functions are useless! because nobody can overwrite it!

Read this article: http://www.gotw.ca/publications/mill18.htm

Nov 17 '05 #3

"Jochen Kalmbach [MVP]" <no********************@holzma.de> skrev i
meddelandet news:ef**************@tk2msftngp13.phx.gbl...
Hi Nemanja!
ref class Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Base");}
public:
void SomeAccessibleFunction()
{SomeVirtualFunction();}
};

ref class Derived : public Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};

int main(array<System::String ^> ^args)
{
Base^ handle = gcnew Derived();
handle->SomeAccessibleFunction();

return 0;
}

I would expect to get "Derived" as the result, right? However, I get
"Base", and strange warnings during compilation:

".\PrivateVirtual.cpp(8) : warning C4486: 'Base::SomeVirtualFunction'
:
a private virtual method of a ref class or value class should be
marked
'sealed'


"private" virtual functions are useless! because nobody can overwrite
it!

You need to declare your virtual functions at least as "protected"!


But note that this is so for managed code only. In real C++ it would
have worked!
Bo Persson
Nov 17 '05 #4
Even in "old" Managed C++ it works.

Nov 17 '05 #5
It seems to be stupid from the C++ programmer's point of view, but then
..NET was not designed by C++ programmers.

Unfortunately in .NET virtual functions can't be private, they must be
protected. But even that modification won't solve your problem, you even
have to declare the function override to override a virtual function.
The correct code is

ref class Base {
protected:
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Base");}
public:
void SomeAccessibleFunction()
{SomeVirtualFunction();}
};

ref class Derived : public Base {
protected:
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};

I share your pain...

Tom

Nemanja Trifunovic wrote:
Something I don't get it:

Say we have:

ref class Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Base");}
public:
void SomeAccessibleFunction()
{SomeVirtualFunction();}
};

ref class Derived : public Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};

int main(array<System::String ^> ^args)
{
Base^ handle = gcnew Derived();
handle->SomeAccessibleFunction();

return 0;
}

I would expect to get "Derived" as the result, right? However, I get
"Base", and strange warnings during compilation:

".\PrivateVirtual.cpp(8) : warning C4486: 'Base::SomeVirtualFunction' :
a private virtual method of a ref class or value class should be marked
'sealed'
.\PrivateVirtual.cpp(16) : warning C4486:
'Derived::SomeVirtualFunction' : a private virtual method of a ref
class or value class should be marked 'sealed'
"

If I try explicit overriding:

.\PrivateVirtual.cpp(17) : error C3671: 'Derived::SomeVirtualFunction'
: function does not override 'Base::SomeVirtualFunction'
.\PrivateVirtual.cpp(16) : warning C4486:
'Derived::SomeVirtualFunction' : a private virtual method of a ref
class or value class should be marked 'sealed'

What is going on here?

Nov 17 '05 #6
Tamas Demjen wrote:
ref class Derived : public Base {
protected:
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};


Sorry I copied the wrong code:

ref class Derived : public Base {
protected:
virtual void SomeVirtualFunction() override
{Console::WriteLine(L"Derived");}
};

Note the override keyword, it indicates that the function is not
replacing Base::SomeVirtualFunction, but is overriding it.

Tom
Nov 17 '05 #7
Hi Tom.
Unfortunately in .NET virtual functions can't be private, they must be protected
But I am pretty sure CLR allows private virtual functions. It works
fine with old MC++.
But even that modification won't solve your problem, you even have to declare the function override to override a virtual function.


Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
like this "controlled virtuality". Just have no idea why to disable
private virtual functions. Any clues?

Nov 17 '05 #8
Nemanja Trifunovic wrote:
Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
like this "controlled virtuality". Just have no idea why to disable
private virtual functions. Any clues?


The reason I don't like this override keyword is that because if you
miss it, the function won't work like a virtual function anymore, and
there's not even a compiler warning. No override keyword == non-virtual
function, even if the virtual keyword is there. It's very frustrating
when you have a virtual function and it's not polymorphic.

If I make the virtual function private, I get the following .NET runtime
exception:

<quote>
An unhandled exception of type 'System.TypeLoadException' occurred in
Virtual.exe

Additional information: Method 'SomeVirtualFunction' on type 'Derived'
from assembly 'Virtual, Version=1.0.1999.26811, Culture=neutral,
PublicKeyToken=null' is overriding a method that is not visible from
that assembly.
</quote>

This is not a language feature, it's a .NET runtime exception, which
clearly states that overriding a private virtual function is not
supported by the runtime library.

I don't know if it's intentional, but this is happening with VC++ 2005
Beta2.

Tom
Nov 17 '05 #9
You are right - it does throw. However, with VC++ 2003, the following
code works just fine:

__gc class Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(S"Base");}
public:
void SomeAccessibleFunction()
{SomeVirtualFunction();}
};
__gc class Derived : public Base {
virtual void SomeVirtualFunction()
{Console::WriteLine(L"Derived");}
};
int _tmain()
{
Base* handle = new Derived();
handle->SomeAccessibleFunction();
return 0;
}

Did they introduce this "feature" in CLR 2.0? That would be very
strange, indeed.

Nov 17 '05 #10
Nemanja Trifunovic wrote:
Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
like this "controlled virtuality". Just have no idea why to disable
private virtual functions. Any clues?


Let me take a wild guess. Interoperability with other .NET languages?
Nov 17 '05 #11
And the same code on VC++2005 with /clr:oldsyntax gives the following
warning:

..\PrivateVirtual.cpp(46) : warning C4445: 'void
Base::SomeVirtualFunction(void)' : in a managed type a virtual method
cannot be private
..\PrivateVirtual.cpp(54) : warning C4445: 'void
Derived::SomeVirtualFunction(void)' : in a managed type a virtual
method cannot be private

But it works just fine!!!

Hehehe, is it weird or what? I'm gonna start ILDasm now to see what's
going on...

Nov 17 '05 #12
Hmmm.. here's the difference:

"/clr:oldsyntax":

..method private virtual instance void SomeVirtualFunction() cil
managed
{
....

"/clr":

..method private hidebysig strict virtual
instance void SomeVirtualFunction() cil managed
{

So the difference is "hidebysig strict" part. AFAIK hidebysig is
ignored by runetime and is used only by tools, but what the heck is
"strict"? I don't remember seing it before...

Nov 17 '05 #13
Nemanja Trifunovic wrote:
Hmmm.. here's the difference:

"/clr:oldsyntax":

..method private virtual instance void SomeVirtualFunction() cil
managed
{
....

"/clr":

..method private hidebysig strict virtual
instance void SomeVirtualFunction() cil managed
{

So the difference is "hidebysig strict" part. AFAIK hidebysig is
ignored by runetime and is used only by tools, but what the heck is
"strict"? I don't remember seing it before...

It means exactly what this thread is about: It prevents a private member
function from being overriden in a derived class. The reason the CLR
added this (and all the Microsoft languages emit this) is that the
design of the BCL and FX and common design pattersn in .NET make this a
security issue. Many base classes base security and threat model
analysis on the fact that a derived class cannot be inserted and change
behavior in the base class (like validation) that needs to bge immune to
being changed by further derived classes.

Ronald Laeremans
Visual C++
Nov 17 '05 #14
Nemanja Trifunovic wrote:
Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
like this "controlled virtuality". Just have no idea why to disable
private virtual functions. Any clues?


Private virtual functions are still useful for one scenario. In ref classes,
in order to override a virtual function, you have to have access to call it.
Since a private virtual function can never be called from outside the class,
it can never be overridden. Thus, to make the compiler stop issuing a
diagnostic for the private virtual function, you can use the "sealed"
keyword.

Now, virtual functions are also used to implement interface contracts. So,
if you want to implement an interface without changing the API exposed
directly from the type, you can implement the funtion with a private sealed
virtual function.

The last thing to bring up is why overriding a virtual function to which you
do not have access is a security issue in ref classes but not native
classes. For ref classes, types can be derived accross assembly boundaries.
Inheriting native classes have never been supported across DLL boundaries
with any fidelity. Many times a ref class would make its virtual functions
"internal" because they were only needed inside the assembly. In version 1.0
of the CLR, any type could override a virtual function. That was intentional
because the CLR wanted to support the C++ semantics. The security issue was
found after 1.0 shipped, and the strict semantics were introduced in version
1.1. C# used the strict semantics in 1.1, and we chose to follow suit with
the new C++ syntax in Visual C++ 2005.

Hope that helps!

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Nov 17 '05 #15
Alexei wrote:
Nemanja Trifunovic wrote:
Yep, just noticed this in the C++/CLI spec. Actually, I pretty much
like this "controlled virtuality". Just have no idea why to disable
private virtual functions. Any clues?


Let me take a wild guess. Interoperability with other .NET languages?


We wanted C++ to be as secure as other languages. :-) It was determined that
giving up the ability to override inaccessible virtual functions was a good
tradeoff with the coding practices that would have to be employed to avoid
the security problems (see my other post).

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Nov 17 '05 #16
Tamas Demjen wrote:
The reason I don't like this override keyword is that because if you
miss it, the function won't work like a virtual function anymore, and
there's not even a compiler warning. No override keyword == non-virtual
function, even if the virtual keyword is there. It's very frustrating
when you have a virtual function and it's not polymorphic.


I'm not sure why you're not seeing a warning because there are plenty of
them for this scenario. In any case, the compiler team decided to change the
warnings into errors after Beta 2. When Visual C++ 2005 ships, you'll be
required to put the "new" or "override" keyword there. The code will not
compile otherwise.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Nov 17 '05 #17
> Hope that helps!

Absolutelly. Thanks a lot for your detailed explanation. I wasn't aware
of the security issue you mention.

Nov 17 '05 #18
Thanks Ronald, it makes sense.

Was "strict" added in CLR 2.0? I don't remember it from v1.1.

Nov 17 '05 #19
Interesting thread - thanks Nemanja :-)

--
Regards,
Nish [VC++ MVP]
http://www.voidnish.com
http://blog.voidnish.com
"Nemanja Trifunovic" <nt*********@hotmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
Hope that helps!


Absolutelly. Thanks a lot for your detailed explanation. I wasn't aware
of the security issue you mention.

Nov 17 '05 #20
Brandon Bray [MSFT] wrote:
I'm not sure why you're not seeing a warning because there are plenty of
them for this scenario. In any case, the compiler team decided to change the
warnings into errors after Beta 2. When Visual C++ 2005 ships, you'll be
required to put the "new" or "override" keyword there. The code will not
compile otherwise.


There is indeed a warning that I overlooked. Excellent, thanks, Brandon.
Sorry for the confusion.

Tom
Nov 17 '05 #21

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: hswerdfe | last post by:
I have several Classes that derive from a common Base Class Each of these Classes Has a Differnt Version of a Function with the Same Short name, but different Long Name. See Bellow: // Base...
0
by: Adriano Coser | last post by:
Hello. I have an ExpandableObjectConverter subclass that I associate to the 'Converter' of a custom property descriptor. After I changed my .net code to the new syntax (VC 2005), the...
1
by: Peter Oliphant | last post by:
I got 2005 Express to prepare for the arrival of my company's MSDN full version. Upon loading my project it was converted successfully, but did warn me modifications would have to be done for it to...
8
by: Edward Diener | last post by:
By reuse, I mean a function in an assembly which is called in another assembly. By a mixed-mode function I mean a function whose signature has one or more CLR types and one or more non-CLR...
17
by: Fabry | last post by:
Hi All, I'm new of this group and I do not know if this is the correct group for my question. I have a DLL with its export library (.lib) wrote in Borland C++ 6. In borland everything is OK and...
10
by: John Goche | last post by:
Hello, page 202 of Symbian OS Explained by Jo Stichbury states "All virtual functions, public, protected or private, should be exported" then page 203 states "In the rare cases where a...
7
by: Amu | last post by:
Hi i am stuck up in a part of project where i have to inherit the VC++ template classes into C#.net. Please provide me the solution for this .
2
by: Amu | last post by:
i have a dll ( template class) ready which is written in VC++6. But presently i need to inherit its classes into my new C#.net project.so if there is some better solution with u then please give me...
14
by: v4vijayakumar | last post by:
Why we need "virtual private member functions"? Why it is not an (compile time) error?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.