Click here to Skip to main content
15,888,527 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have a little problem that I can not figure out the solution, if exist (I really hope so :) ). I have one base class, Base, and inside of it, I have two nested classes, A and B (class B is derived from A). In class A, I have two operatores: increment posfix and addition assignment. In class B, I only have the increment prefix (code below).

My problem is: Why it is call the increment prefix operator instead of the increment posfix operator when I do b++?

Best regards,
Filipe Marques

Code:

C++
#include <stdio.h>

class Base
{
public:
	class A
	{
	protected:
		A() {}
	public:
		A& operator++(int)
		{
			printf("1\n");
			return A();
		}

		A& operator+=(unsigned int __num)
		{
			printf("2\n");
			return A();
		}
	};

	class B : public A
	{
	public:
		B() : A() {}

		B& operator++()
		{
			printf("3\n");
			return B();
		}
	};

	B get_b()
	{
		return B();
	}
};

void main()
{
	Base base;
	Base::B b = base.get_b();

	// No problem
	b += 1;

	// warning C4620:	no postfix form of 'operator ++' found
	// for type 'Base::B', using prefix form
	b++;
}


The output id:
2
3
Posted

What happens here is "hiding".

First an example for normal functions:
C++
class A
{
public:
  void f(); // 1
};
class B: public A
{
public:
  void f(int); // 2
};


The function at 2 hides the one at 1. You can circumvent this by a using A::f; in B.

The operator++ has two signatures: one without an argument and the other with argument. When calling one or the other, you have two options, e.g. for operators as class members:

implicit callexplicit call
C++
++a;
C++
a.operator++();
C++
a++;
C++
a.operator++(0);

The definition in the class is:
C++
class C
{
public:
  C& operator++();    // prefix overload:  ++a
  C  operator++(int); // postfix overload: a++
};


So, finally: since the two operators are overloads of each other, you hide in your B class the one from the A class.
Cheers
Andi

PS: The warning says it all ;-). That the compiler decides to take the "wrong" operator is debatable, but the warning tells that it does so.
 
Share this answer
 
v2
Comments
Filipe Marques 19-Oct-13 10:27am    
Hi Andreas Gieriet, please, see the answers that I wrote for Pwasser solution. Best regards, Filipe Marques
Andreas Gieriet 19-Oct-13 17:23pm    
You are very welcome!
Cheers
Andi
Joezer BH 21-Oct-13 9:43am    
5ed! very nice answer
Andreas Gieriet 21-Oct-13 10:45am    
Hello Canny Brisk,
thanks for your 5!
Cheers
Andi
Andreas Gieriet has given the explanation very clearly.

If you wish to reintroduce operator++ from A into the scope of B you may employ
C++
using
.

http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.aix.doc/language_ref/using_declaration_class_members.html[^]

So then:
C++
	class B : public A
	{
	public:
		using A::operator++;
		B() : A() {}
 
		B& operator++()
		{
			printf("3\n");
			return B();
		}
	};
 
	B get_b()
	{
		return B();
	}
};
 
Share this answer
 
v2
Comments
nv3 18-Oct-13 5:45am    
A 5 to both of you guys for the interesting explanation.
[no name] 18-Oct-13 8:59am    
Thankyou
Filipe Marques 19-Oct-13 10:25am    
Andreas Gieriet and Pwasser, thanks for yours answers. I did not know the hide concept. I thought that a method is declared as public in base class, keeps accessible from derived class (for same methods with differents signatures). One more time, thanks for your answers :) . Best regards, Filipe Marques
[no name] 19-Oct-13 19:07pm    
Thanks & Cheers

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