c++提供了关键字explicit,禁止通过构造函数进行隐式转换。声明为explicit的构造函数不能在隐式转换中使用。
#include
using namespace std;
class Data
{
private:
int num;
public:
Data()
{
cout<<"Data无参构造"<<endl;
}
//初始化列表:对象名+() 显示调用 调用对象成员的构造函数
explicit Data(int a):num(a)
{
//data =c;
cout<<"Data有参构造"<<endl;
}
~Data()
{
cout<<"Data析构函数"<<endl;
}
};
int main(int argc, char *argv[])
{
//当explicit修饰构造函数,不允许隐式转换
Data data = 10;
Data data1(15);//ok
Data data2 = Data(20);//ok
cout << "Hello World!" << endl;
return 0;
}
运行结果:
(1)malloc返回一个void指针,c++不允许将void赋值给其他任何指针,必须强转。
(2)malloc可能申请内存失败,所以必须判断返回值来确保内存分配成功。
(3)maloc不会调用构造函数,free不会调用析构函数(重要的)
void test01(){
int* a = new int;
*a = 100;
cout<<"*a = "<<*a<<endl;//100
delete a;
}
void test02(){
int *a = new int[5];//申请内容的时候,内容没有初始化,值随机。
int *b = new int[5]{1,2,3,4,5};//值初始化。
for(int i = 0; i < 5; i++){
cout << a[i] << " ";
}
cout << endl;
delete [] a;//new时加了[],delete也必须加[].
for(int i = 0; i < 5; i++){
cout << b[i] << " ";
}
cout << endl;
delete [] b;
//char *b = new char[15]{"hehe"};//错误
char *arr = new char[15];
strcpy(arr,"hehe");
cout << arr << endl;
delete [] arr;
}
运行结果:
注意:(1)new没有加[],delete释放的时候就不加[].
(2)new加[],delete释放的时候就加[].
void test03(){
//new按照Data申请空间,如果申请成功,会自动调用构造函数。
Data *data = new Data();
//先调用析构函数,在释放空间
delete data;
}
运行结果:
class Data
{
private:
int num;
char *str;
public:
Data()
{
cout<<"Data无参构造"<<endl;
}
//初始化列表:对象名+() 显示调用 调用对象成员的构造函数
Data(int a,char *str1):num(a),str(str1)
{
cout<<"Data有参构造"<<endl;
}
~Data()
{
cout<<"Data析构函数"<<endl;
}
void showData(){
cout << num << " " << str << endl;
}
};
void test04(){
Data *data = new Data(100,"hehe");
//因为data是指针,所以使用->,如果是普通对象,则使用.
data->showData();
delete data;
}
运行结果:
本质还是数组,只是数组的每个元素是类的对象
void test05(){
char *data = "hehehehe";//该方法只适合于字符串。char *data = {'w','s'}的方法是错误的,其他类型这样创建数组也是错误的。
int arr[3];
//对象数组arr1是数组,每个元素是Data类型的对象。
//定义对象数组的时候,系统会自动给的数组中的每个元素调用构造函数。
//自动调用无参构造
Data arr1[5];
}
运行结果:
void test06(){
//对象数组arr1是数组,每个元素是Data类型的对象
//定义对象数组的时候 系统会自动给数组中的每个元素调用构造函数
//人为为元素调用有参构造
//初始化部分 调用有参构造 未初始化部分自动调用默认构造(无参构造)
Data arr2[5] = {Data(50,"haha"),Data(60,"xixi")};
//arr2[0]第0个元素,就是Data的对象
arr2[0].showData();
arr2[1].showData();
}
运行结果:
void test07(){
Data *arr1 = new Data[5];//调用无参构造
delete [] arr1;
//第二种方法,调用有参构造
Data *arr2 = new Data[5]{Data(50,"haha"),Data(60,"xixi")};
//访问数组的不同方式
(*arr2).showData();
arr2[0].showData();
(arr2+1)->showData();
delete [] arr1;
}
运行结果:
注意:没有析构 ,这是因为data1指向的类型未void,无法从void中寻找响应析构函数
成员:成员变量、成员函数
static修饰成员变量和成员函数
static声明为静态的,称为静态成员。不管这个类创建了多少对象,静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。
静态成员属于类,而不是对象。
静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间
静态变量必须在类内声明,类外定义(普通成员变量可以类内定义)。
静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占的空间。
class Data2{
public:
int num;//普通成员变量
static int data;//静态成员变量
};
//定义的时候不需要加static
int Data2::data = 100;
void test(){
//data是静态成员变量,是属于类的,可以通过类名称::直接访问
cout << Data2::data << endl;//100
//赋值
Data2::data = 200;
cout << Data2::data << endl;//200
Data2 *ob1 = new Data2();
//静态成员变量也可以使用对象名进行访问
ob1->data = 300;
cout << Data2::data << endl;//300
Data2 *ob2 = new Data2();
cout << ob2->data << endl;//300
//普通成员变量只可以用成员名进行访问
ob1->num = 100;
cout << ob2->num << endl;//随机值
}
class Data2{
private:
int num;//普通成员变量
static int data;//静态成员变量
public:
//静态成员函数属于类而不属于对象
static int getData(){
return data;
}
};
//定义的时候不需要加static
int Data2::data = 100;
void test10(){
//静态成员函数可以通过类名直接访问
cout << Data2::getData()<<endl;
//也可以通过对象名进行访问
Data2 *ob1 = new Data2();
cout << ob-> getData() << endl;;
}
注意:1、静态成员函数的目的是操作静态成员数据
2、静态成员函数不能访问非静态成员数据。(静态成员函数内部没有this指针)
3、普通成员函数可以操作静态成员数据和非静态成员数据
class Data2{
private:
int num;//普通成员变量
static int data;//静态成员变量
public:
int getNum(){
num = 100;//no-static
return data;//static
}
static int getData(){
return data;
}
};
4、静态成员变量和静态成员函数都有权限之分
如果一个类的成员,既要实现共享,又要实现不可改变,那就用static const修饰