C++对象和类二
主要内容
- this指针
- 对象数组
this指针
我们在上一次博客中定义了一个Dog类,这里再贴一遍上次的代码
(水一下篇幅)
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
class Dog //这是一个类的声明
{
private://私有
char m_name[30];
int m_age;
char m_color[20];
public://公有
Dog();
Dog(char name[],int age,char color[]);
~Dog();
void howl(int time);
void running(int time,char location[]);
void show();
};
Dog :: Dog()
{
strncpy(m_name, "no_name",30);
m_age=0;
strncpy(m_color,"unknown",20);
}
Dog :: ~Dog()
{
//这是一个析构函数
cout << "bye! My dear dog, "<<m_name<<"\n";
}
Dog :: Dog(char name[],int age, char color[])
{
strncpy(m_name, name,30);
m_age = age;
strncpy(m_color,color,20);
}
void Dog::howl(int time)
{
cout << m_name <<" has howled for " << time <<" seconds\n";
}
void Dog::running(int time,char location[])
{
cout << m_name <<" has ran for "<<time<<" seconds in the "<<location<<"\n";
}
void Dog::show()
{
cout << "name : " <<m_name<<"\n";
cout << "age : "<<m_age<<"\n";
cout << "color : "<<m_color << "\n";
}
int main()
{
Dog dog1("Peter",2,"white");//隐式调用构造函数
//显式调用构造函数: Dog dog1 = Dog("Peter",2,"white")
dog1.show();
dog1.howl(30);
char location[30]="playground";
dog1.running(60,location);
Dog dog2 = Dog();//注意默认参数无法进行隐式调用
dog2.show();
return 0;
}
我们可以看到每个类成员函数都只涉及到一个对象,即调用它的对象
但是如果有的时候方法可能涉及到两个对象
在这种情况下需要使用C++的this指针
我们看这样一个函数:
比较两只Dog类实例对象的年龄,返回年龄较大的那一个
因为是两个对象的比较,所以我们可以在任意一个对象的方法中调用这个compare函数都是可行的
compare函数:
const Dog & Dog::compare(const Dog& s) const
//最后一个const限定this为const,这样将不能使用this来修改对象的值
//前面两个const也是用来防止修改数据
//这里是引用传递
{
if(s.m_age>m_age)
return s;
else
return *this;//返回this指针指向的地址
}
上述代码相当于隐式的访问了一个对象(拥有这个方法的对象),显式的访问了另外一个对象,并返回其中一个对象的引用
如果没有this指针,我们在else模块中我们如何返回原本的方法的对象呢?——我们无法称呼这个对象,因为它在函数中并没有实例化,另外一个对象有引用调用的s,而它没有——这里就是this指针发挥作用的时候了
this指针:每个成员函数(保护构造函数和析构函数)都有一个this指针指向调用对象,如果方法需要引用整个对象,则我们使用
(这里打不出来星号)this
(将解除引用操作符*用于指针,就可以得到指针指向的值)
对象数组
用户通常需要创建同一个类的多个对象,所以我们自然想到了数组
对象数组的声明跟其他数组的声明是一样的
Dog mydogs[5];//对象数组的声明
注意这里,如果程序创建为被显式初始化的类对象时,总是调用默认构造函数,所以上述声明将会自动调用隐式默认构造函数
Dog :: Dog()//隐式默认构造函数
{
strncpy(m_name, "no_name",30);
m_age=0;
strncpy(m_color,"unknown",20);
}
当然我们同样可以使用显式构造函数函数来初始化数组元素
必须为每个元素都调用构造函数
具体代码示例:
const int number = 5;
Dog mydogs[number]={
Dog("Mike",3,"black"),//显式构造函数
Dog(),//隐式默认构造函数
Dog("Scout",10,"yellow"),
};
注意这里只初始化了数组中的前三个元素,剩下的两个元素没有声明,那么将使用隐式默认构造函数进行初始化
ps:要创建类对象数组,则这个类必须有默认构造函数
最后完善后的整个代码:
#include <iostream>
#include <cstring>
using namespace std;
class Dog //这是一个类的声明
{
private://私有
char m_name[30];
int m_age;
char m_color[20];
public://公有
Dog();//默认构造函数
Dog(char name[],int age,char color[]);//显式构造函数
~Dog();//析构函数
void howl(int time);//具体的成员函数
void running(int time,char location[]);
void show();
const Dog & compare(const Dog&s) const;//使用this指针的函数
};
const Dog & Dog::compare(const Dog& s) const
{
if(s.m_age>m_age)
return s;
else
return *this;
}
Dog :: Dog()
{
strncpy(m_name, "no_name",30);
m_age=0;
strncpy(m_color,"unknown",20);
}
Dog :: ~Dog()
{
//这是一个析构函数
cout << "bye! My dear dog, "<<m_name<<"\n";
}
Dog :: Dog(char name[],int age, char color[])
{
strncpy(m_name, name,30);
m_age = age;
strncpy(m_color,color,20);
}
void Dog::howl(int time)
{
cout << m_name <<" has howled for " << time <<" seconds\n";
}
void Dog::running(int time,char location[])
{
cout << m_name <<" has ran for "<<time<<" seconds in the "<<location<<"\n";
}
void Dog::show()
{
cout << "name : " <<m_name<<"\n";
cout << "age : "<<m_age<<"\n";
cout << "color : "<<m_color << "\n";
}
int main()
{
Dog dog1("Peter",2,"white");//隐式调用构造函数
//显式调用构造函数: Dog dog1 = Dog("Peter",2,"white")
dog1.show();
dog1.howl(30);
char location[30]="playground";
dog1.running(60,location);
Dog dog2 = Dog();//注意默认参数无法进行隐式调用
dog2.show();
const int number = 5;//创建对象数组
Dog mydogs[number]={
Dog("Mike",3,"black"),
Dog(),
Dog("Scout",10,"yellow"),
};
Dog top = mydogs[0];//创建一个类对象
for(int i=1;i<number;i++)//循环比较
top = top.compare(mydogs[i]);
cout << "\n My oldest dog's information:\n";//输出结果
top.show();
return 0;
}
输出结果:
name : Peter
age : 2
color : white
Peter has howled for 30 seconds
Peter has ran for 60 seconds in the playground
name : no_name
age : 0
color : unknown
My oldest dog's information://这里输出了比较后的信息
name : Scout
age : 10
color : yellow
bye! My dear dog, Scout//这里有两个scout是因为Dog top最后是它的引用变量
bye! My dear dog, no_name
bye! My dear dog, no_name
bye! My dear dog, Scout
bye! My dear dog, no_name
bye! My dear dog, Mike
bye! My dear dog, no_name
bye! My dear dog, Peter
//一共创建了八个实例,程序结束时都会自动调用析构函数进行清理
下一篇预告:操作符重载、友元函数
码字不易,点个赞吧