子类对象代替父类对象作为函数入口参数(以及对类私有成员变量继承的理解)

1.子类对象代替父类对象作为函数入口参数

从一个简单的例子中就可以清楚的看出:

#include <iostream>
using namespace std;

class father
{
public:
	virtual void show()
	{
		cout<<"father value\n";
	}
};

class child : public father
{
public:
	virtual void show()
	{
		cout<<"child value\n";
	}
};

void test_show(father temp1, father *temp2, father &temp3)
{
	temp1.show();
	temp2->show();
	temp3.show();
}

int main()
{
  child c;
  test_show(c, &c, c);  
	return 0;
}

结果如下:

可以看出,当入口参数为父类对象时,子类即便作为入口参数,最后使用的仍然是父类的方法,而入口参数是父类指针或者父类引用时,子类代替父类作为入口参数,就可以使用自己的方法。

2.测试过程中发现的问题(对类私有成员变量继承的理解)

在编写测试程序过程中,我一开始编写的程序是这样的(错误的):

#include <iostream>
using namespace std;

class father
{
public:
	father(int t):a(t){};
	virtual void show()
	{
		cout<<"father value"<<a<<endl;
	}
private:
	int a;
};

class child : public father
{
public:
	child (int t1, int t2):a(t1),b(t2){};
	virtual void show()
	{
		cout<<"child value"<<a<<" "<<b<<endl;
	}
private:
	//int a;
	int b;
};

void test_show(father temp1, father *temp2, father &temp3)
{
	temp1.show();
	temp2->show();
	temp3.show();
}

int main()
{
  child c(1,2);
  test_show(c, &c, c);  
	return 0;
}

这个程序的错误主要是因为我对私有成员变量的继承理解不够。

子类在继承父类时,确实把所有的成员都继承下来了,但是对于私有成员变量确没有访问权限,访问权限表如下所示:

以私有继承为例,父类中的public对象和protected对象在子类中是private对象,父类中private对象,子类是无法直接拿来使用的。但是私有继承中父类的成员都无法在子类对象中使用,可以参考另一张表格来对照看

 

 

所以这个程序的问题就是直接访问了父类的私有成员变量,无论是在构造函数中的初始化列表,还是在show函数中的打印,都是直接访问了父类私有成员变量。要想让子类可以访问父类的私有成员变量,只可以自己构造成员函数set和get,更改的程序如下:

#include <iostream>
using namespace std;

class father
{
public:
	//father(int t):a(t){};
	int getf(){return a;}
	void setf(int t){a=t;}
	virtual void show()
	{
		cout<<"father value "<<getf()<<endl;
	}
private:
	int a;
};

class child : public father
{
public:
	//father (int t1, int t2):a(t1),b(t2){};
	int getc(){return b;}
	void setc(int t1, int t2){setf(t1);b=t2;}
	virtual void show()
	{
		cout<<"child value "<<getf()<<" "<<getc()<<endl;
	}
private:
	//int a;
	int b;
};

void test_show(father temp1, father *temp2, father &temp3)
{
	temp1.show();
	temp2->show();
	temp3.show();
}

int main()
{
  child c;
  c.setc(1,2);
  test_show(c, &c, c);  
	return 0;
}

还有一种初始化列表的更改版本:

using namespace std;

class father
{
public:
	father(int t) :a(t){};
	int getf(){ return a; }
	virtual void show()
	{
		cout << "father value" << a << endl;
	}
private:
	int a;
};

class child : public father
{
public:
	child(int t1, int t2) :father(t1), b(t2){};//特别注意这里这种初始化方法
	virtual void show()
	{
		cout << "child value" << getf() << " " << b << endl;
	}
private:
	//int a;
	int b;
};

void test_show(father temp1, father *temp2, father &temp3)
{
	temp1.show();
	temp2->show();
	temp3.show();
}

int main()
{
	child c(1, 2);
	test_show(c, &c, c);
	system("pause");
	return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值