类
C++中的类包含:类成员
、构造函数
、析构函数
、成员函数
以及它们的访问属性public
、private
、protected
。类成员缺省private
。
类的定义:
class Dog
{
public:
Dog(const Dog &str);
void SetAge(int age);
void ShowAge();
void SetName(char *name);
void ShowName();
Dog(char *name,int age);
Dog();
virtual ~Dog();
private:
int age;
char *name;
};
成员函数的实现:
void Dog::ShowName()
{
std::cout << name << std::endl;
}
void Dog::SetName(char *name)
{
if (!name)
{
strcpy(name," ");
}
strcpy(this->name,name);
}
void Dog::ShowAge()
{
std::cout << age << std::endl;
}
void Dog::SetAge(int age)
{
if(age >= 0)
{
this->age = age;
}
}
C++允许函数重载,我们可以自定义多个构造函数,但析构函数只有一个;
构造函数
在创建类对象时,C++会自动调用构造函数,创建对象。
构造函数的几种形式:
Dog()
{
std::cout << "调用默认构造函数" << std::endl;
this->name = new char[1024]();
strcpy(name," ");
this->age = 0;
}
Dog(char *name, int age)
{
std::cout << "调用自定义构造函数" << std::endl;
this->name = new char[1024]();
if (!name)
{
strcpy(name," ");
}
strcpy(this->name,name);
this->age =age;
}
//复制构造函数
Dog(const Dog &str)
{
std::cout << "调用复制构造函数" << std::endl;
this->name = new char[1024]();
strcpy(this->name,str.name);
this->age = str.age;
}
显示构造与隐式构造
在构造函数只有一个参数时,在调用构造该类时,有可能会发生隐式构造。例:
Dog::Dog(int age)
{
std::cout << "调用age构造函数" << std::endl;
this->name = new char[1024]();
strcpy(this->name," ");
this->age = age;
}
Dog dog = 2;
编译器会将自动创建调用dog(2)
,然后发生复制构造。
加上explicit
关键字后,编译器会报
error C2440: 'initializing' : cannot convert from 'const int' to 'class Dog'No constructor could take the source type, or constructor overload resolution was ambiguous
为了避免隐式构造,在构造函数声明时,加上explicit
关键字。
析构函数
一个类里面只有一个析构函数。
一般在构造函数里面申请了资源,会在析构函数里面释放;如果没释放资源,会造成内存泄漏或者其他问题。
例如:在构造函数里面:
- 打开文件、流
- 申请了内存
- 连接了数据库
析构函数的写法:
//函数申明
virtual ~Dog();
//函数实现
Dog::~Dog()
{
delete name;
this->name = NULL;
}
函数重载
C++编译器允许出现重名函数,但函数的参数与返回值必须不同。
例:
第一种情况:
void test(void);
int test(void);
第二种情况:
void test(int a);
void test(int a,int b = 0);
第三种情况:
void test(int a);
void test(int a,int b);
第四种情况:
void test(char s,int a);
void test(int a,char s);
情况一二是错误的写法,在调用时,编译器无法确定调用哪一个函数;
函数重载的好处:
- 增加程序的可读性
- 对外提供类似功能的统一接口