Click here to Skip to main content
15,890,527 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I have a nested class

int testfunction()
{
	CDCDirectControls::Graphic::Button y;
	y.isNew.Set();
	CDCDirectControls x1;
	x1.Graphic.Button.isNew.Set();  // does not compile with error

	return 1;
}


I get the following output:

1>------ Build started: Project: bmpLoad, Configuration: Debug Win32 ------
1>  CDCDirectControls.cpp
1>c:\users\stephen\desktop\stephen\cppprojects\samplemfc\bmpload\bmpload\cdcdirectcontrols.h(93): warning C4832: token '.' is illegal after UDT 'CDCDirectControls::Graphic'
1>          c:\users\stephen\desktop\stephen\cppprojects\samplemfc\bmpload\bmpload\cdcdirectcontrols.h(44) : see declaration of 'CDCDirectControls::Graphic'
1>c:\users\stephen\desktop\stephen\cppprojects\samplemfc\bmpload\bmpload\cdcdirectcontrols.h(93): error C2274: 'function-style cast' : illegal as right side of '.' operator
1>c:\users\stephen\desktop\stephen\cppprojects\samplemfc\bmpload\bmpload\cdcdirectcontrols.h(93): error C2228: left of '.Button' must have class/struct/union
1>c:\users\stephen\desktop\stephen\cppprojects\samplemfc\bmpload\bmpload\cdcdirectcontrols.h(93): error C2228: left of '.isNew' must have class/struct/union
1>c:\users\stephen\desktop\stephen\cppprojects\samplemfc\bmpload\bmpload\cdcdirectcontrols.h(93): error C2228: left of '.Set' must have class/struct/union
1>  Generating Code...
1>  Skipping... (no relevant changes detected)
1>  bmpLoadView.cpp
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


I have pinned the error down to the line marked with "does not compile with error".

Update #1:

I defined variables inside the class itsGraphic, itsButton, and so forth and then it works like this without a compiler error. But is there a better way of doing it with the calling variable? Is there a better syntax?

Otherwise, when I split the header from the cpp file, I need to be careful to put the variable definition on the cpp side.

C++
int testfunction()
{
	CDCDirectControls::Graphic::Button y;
	y.isNew.Set();
	CDCDirectControls x1;
	x1.itsGraphic.itsButton.isNew.Set();


	return 1;
}



Questions:

1) If one has a variable of the base class, what is the proper way to access the nested class methods?

1a) Is there a method independent of defining a variable in the class? (I guess a pointer could be defined; but is there anything cleaner than that?)

x1.itsGraphic->itsButton->isNew.Set(); //compiles fine when itsGraphic is defined as a pointer to Graphic in the class, but is there a cleaner way to access the nested class methods from the base class?


2) Is the only way to reference the nested class from the base class variable - to create a variable and then access the variable?

References:

Nested Class Declarations[1]

Initializing nested classes - C++ Forum[2]
Posted
Updated 25-Jan-16 0:39am
v6
Comments
Sergey Alexandrovich Kryukov 25-Jan-16 10:14am    
You don't show your class, only the function.
—SA
Philippe Mori 25-Jan-16 21:52pm    
Nested classes essentially only affect the type name of a variable (and its visibility)...

We don't see the definitions of your classes and clearly the usage a re contradictory. In C++, each symbol in ::, -> and . (dot) do something different and are not interchangeable.

In your case, I'm not sure that the use of nested class is appropriate. Usually, you would use nested class only when the nested class is either not used externally or used for specific purpose (like iterator in STL containers) and directly tied to that class.
Philippe Mori 25-Jan-16 21:55pm    
Lot of information but crucial information is missing.

1 solution

If you have an object of a specific type, you can not access members of classes that are derived from that object.

But a common situation is that you have a reference to an object that should be used elsewhere (e.g. passed as parameter to another function) using the type of a base class. In this case you can cast the passed reference to the real type or use virtual functions.

Casting (dynamic_cast conversion - cppreference.com[^]) requires that you know the real type by run-time type information (RTTI) (see Type support (basic types, RTTI, type traits) - cppreference.com[^] and Run-Time Type Information - MSDN[^]) or having a member in the base class that is unique for each derived class.

Using virtual functions is the smarter solution.

When your derived classes should provide a function isNew(), add that as virtual (virtual function specifier - cppreference.com[^]) to the base class and the derived classes. If the base class is abstract (not used itself as variable or member) it can be a pure virtual function (see Abstract Classes - cppreference.com[^]) to ensure that it is implemented in all derived classes.
 
Share this answer
 
Comments
StephenJElliott 26-Jan-16 7:45am    
Hello Jochen, I appreciate your suggestion; I tried a sample, but I ran a little bit into an issue about getting that to compile, so I wrote another issue (See: http://www.codeproject.com/Questions/1074434/How-can-I-used-a-virtual-method-override-it-within? ). For now, I am redefining the subclass explicitly until I understand the errors I am encountering better, so I am not yet ready to accept the solution until I understand it better. If you have additional references at a basic level I would appreciate it. Specifically, I am looking for an example of nested classes in c++ with overload within. What I found instead uses struct constructs and I am unable to convert that over yet to class and I cannot figure out why yet. Once I know more, than I would feel more comfortable coding with it, so I appreciate further assistance.
Jochen Arndt 26-Jan-16 8:07am    
I saw your other question. But it is not related to this question (while it came up with my answer).

I wrote my answer to give you possible directions because a more specific answer requires to know better what you want to to. It looks like you want to define a structure of control elements:
- Control
  - Graphic
    - Button
    - Other graphic element
  - Other control
    - Other control element
and to define some common and element specific methods for these.

It may be possible to use nested classes but I don't see that it is mandatory. You might even recognise later that it was a bad idea and you have to rewrite your code to use normal derived classes.

As Richard wrote in his comment to the other question:
It can become obfuscated and is therefore hard to understand.

I will not keep you from using and learning about nested classes. But if you are actually developing a real application, you should think about not using them. Have always in mind that such code has to be maintained by you and maybe others. Even you might have problems to understand such code if not touched it for some time.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900