友元关系
#include<iostream>
#include<string>
class Lovers
{
public:
Lovers( std::string theName );
void kiss( Lovers *lover );
void ask( Lovers *lover,std::string something );
protected:
std::string name;
friend class Others;
};
Lovers::Lovers(std::string theName)
{
name=theName;
}
void Lovers::ask(Lovers *lover,std::string something)
{
std::cout<<name<<":"<<lover->name<<something<<std::endl;
}
void Lovers::kiss(Lovers*lover)
{
std::cout<<name<<"成功kiss到了"<<lover->name<<std::endl;
}
class Boyfiend:public Lovers
{
public:
Boyfiend(std::string theName);
};
Boyfiend::Boyfiend(std::string theName):Lovers(theName)//这里纠结了好久,要显式的调用父类的构造函数
{
}
class Girlfriend:public Lovers
{
public:
Girlfriend(std::string theName);
};
Girlfriend::Girlfriend(std::string theName):Lovers(theName)
{
}
class Others
{
public:
Others(std::string theName);
void kiss(Lovers *lovers);
protected:
std::string name;
};
Others::Others(std::string theName)
{
name=theName;
}
void Others::kiss(Lovers *lover)
{
std::cout<<name<<"偷亲到了"<<lover->name<<std::endl;
}
int main()
{
Boyfiend boyfriend("小明");
Girlfriend girlfriend("小红");
Others others("老王");
girlfriend.kiss(&boyfriend);
girlfriend.ask(&boyfriend,"回家吃饭!!!");
std::cout<<"\n老王上线——————————————————\n";
others.kiss(&girlfriend);
return 0;
}
子类构造函数的写法
最近几天在看《C++编程实战》的时候,在一段代码中遇到了C++继承的构造函数该怎么写的问题,当时不是很明白。后来,自己上网查阅相关的资料,终于把这个问题搞清楚了。为了自己以后的不时之需,特地将其进行了一个简要的总结。
我们知道,构造方法是用来初始化类对象的。如果在类中没有显式地声明构造函数,那么编译器会自动创建一个默认的构造函数;并且这个默认的构造函数仅仅在没有显式地声明构造函数的情况下才会被创建创建。
构造函数与父类的其它成员(成员变量和成员方法)不同,它不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。如果子类的构造函数没有显示地调用父类的构造函数,则默认调用父类的无参构造函数,至于什么事显式调用,在下面会详细说明!关于子类中构造函数的构造原则,总结如下,欢迎大家指导与批评。
1.父类没有声明构造函数
(1)子类也没有声明自己的构造函数,则父类和子类均由编译器生成默认的构造函数。
(2)子类中声明了构造函数(无参或者带参),则子类的构造函数可以写成任何形式,不用顾忌父类的构造函数。在创建子类对象时,先调用父类默认的构造函数(编译器自动生成),再调用子类的构造函数。
2.父类只声明了无参构造函数
如果子类的构造函数没有显式地调用父类的构造,则将会调用父类的无参构造函数。也就是说,父类的无参构造函数将会被隐式地调用。
3.父类只声明了带参构造函数
在这种情况下,要特别注意。因为父类只有带参的构造函数,所以如果子类中的构造函数没有显示地调用父类的带参构造函数,则会报错,所以必需显示地调用。关于构造函数的显示调用,参见下例。