Effective C++ Item 33: Avoid obscuring inherited names

This topic has little to do with inheritance, and is mainly about understanding and grasping the scope .

Or look at the code:

class Base {
private:
	int x;
public:
	virtual void mf1() = 0;
	virtual void mf1(int);
	virtual void mf2();
	void mf3();
	void mf3(double);
};
class Derived : public Base {
public:
	virtual void mf1();
	void mf3();
	void mf4();
};
intmain()
{
	Derived d;
	int x = 1;
	d.mf1();//No problem, call Derived::mf1()
	d.mf1(x);//Error, Derived::mf1() obscures the Base::mf1 function
	d.mf2();//No problem, call Derived::mf2()
	d.mf3();//No problem, call Derived::mf3()
	d.mf3(x);//Error, Derived::mf1() obscures the Base::mf3 function
	return 0;
}

In the above code, mf1 and mf3 in the subclass mask all functions named mf1 and mf3 in the base class, so Base::mf1 and Base::mf3 are no longer inherited by Derived.

The advantage of this is to avoid creating new subclasses in the library or application framework, incidentally inheriting overloaded functions from estranged base classes . As in the example, the inheritance of the overloaded functions of the mf1 and mf3 functions in the base class is avoided.

In public inheritance, the relationship between the subclass and the base class is "is-a", which means that the subclass has all the things of the base class. If you use public inheritance without inheriting the overloaded functions in the base class, it violates the public meaning of inheritance .

In order to realize the "is-a" relationship between the subclass and the base class in public inheritance, there are two schemes:

1. Option 1: Use using declarative implementation:

class Base {
private:
	int x;
public:
	virtual void mf1() = 0;
	virtual void mf1(int);
	virtual void mf2();
	void mf3();
	void mf3(double);
};
class Derived : public Base {
public:
	using Base::mf1; // Make Base::mf1 visible in subclasses using the using declarative
	using Base::mf3; // Make Base::mf3 visible in subclasses using the using declarative
	virtual void mf1();
	void mf3();
	void mf4();
};
intmain()
{
	Derived d;
	int x = 1;
	d.mf1();//No problem, call Derived::mf1()
	d.mf1(x);//No problem, call Base::mf1 function
	d.mf2();//No problem, call Derived::mf2()
	d.mf3();//No problem, call Derived::mf3()
	d.mf3(x);//No problem, call the Base::mf3 function
	return 0;
}

Solution 1 solves the problem of obscuring the overloaded function of the base class due to redefining the function in the subclass. The using declaration makes functions in the base class visible in the subclass scope. However, we may not always want all the functions of the inherited base class to be visible in the subclass. How to meet such a requirement?

2. Scheme 2 uses private inheritance, and uses forwarding function in inheritance to solve the above problems:

class Base {
private:
	int x;
public:
	virtual void mf1() = 0;
	virtual void mf1(int);
};
class Derived : private Base {
public:
	virtual void mf1() {
		Base::mf1();//Transfer function, only inherit the mf1 function of the base class without parameters
	}
};
intmain()
{
	Derived d;
	int x = 1;
	d.mf1();//No problem, call Derived::mf1()
	d.mf1(x);//Error, Base::mf1 function is masked
	return 0;
}

In the mf1 function of the subclass, the tasks that the mf1 function needs to perform are handed over to the mf1 function of the Base class for execution.

In which, only the parameterless function of Base's mf1 function is called, which achieves the goal of masking the mf1 parameterized function.

3. Summary:

  1. The essence of the problem of name masking is the understanding of the scope. If you can understand the scope well, the problem of name masking is not difficult.
  2. There are using declarative and transfer function methods to solve the problem of name masking, and an appropriate solution can be selected according to the actual application scenario.
  3. For questions about transfer functions, please refer to Clause 46 of "Exceptional C++", which has a detailed introduction to transfer functions.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324845325&siteId=291194637