C++中各个构造函数原理

命名空间

//声明std,我们的函数可以直接使用里面的成员,不需要使用std::
using namespace std

//自定义命名空间
namespace abce{
	int age = 33;
	char * name = "我是猛男";
	void show(){
		cout << "name:" << name << ",age:" << age << endl;
	}
};

namespace a{
	namespace b{
		c(){}
	}
}

int main(){
	cout << "命名空间" << endl;
	using namespace bace;//在方法里声明,仅限在当前方面里面使用
	int ageValue = abce::age; //方式1
	ageValue = age; //方式2 直接引用
	show();
	//命名空间里面重复的函数怎么办?使用方式1
	using namespace a::b//命名空间嵌套
	c();
	a::b::c();
	return 0;
}

构造函数详解

//student.h 头文件
class Student{
	public:
		Student(){
		cout << "空参数构造函数" << endl;
	}
	//一个参数的构造函数
	Student (char * name) {
		cout << "一个参数构造函数" << endl;
		this->name = name;
	}
	Student(char * name):name(name){
		cout << "一个参数构造函数" << endl;// 跟上面的等价
	}

	Student(char * name):Student(name,88){//先调用两个构造函数的再调用当前
		cout << "一个参数构造函数" << endl;
	}

	Student(char * name, int age){
		this->name =char *(malloc(sizeof (char *) * 10));
		strcpy(this->name, name)
		this->age = age;
		cout << "两个参数构造函数" << endl;
	}

	Student(char * name, int age)name(name),age(age){//直接赋值
	
	}
	
	//析构函数 Student对象的临终遗言,被回收前做一些释放工作
	~Student(){//不能传参
		//free 不会执行析构函数,malloc也不会调用构造函数
		cout << "调用delete,执行析构函数" << endl;
		//比如上面的两个构造函数的name,创建了一个在堆区的对象
		if(this->name) {
			free(this->name);
			this->name = NULL;
		}
	}
	private:
	char * name;
	int age;
	public:
	// set get
	void setAge(int age);//声明函数
	void setName(char * name);
	void getAge();
	char * getName();
};
#include "Student.h"
// 根据Student.h 头文件 写实现 Student.cpp

void Student::setAge(int age){
	// -> 调用一级指针,C++对象指向的是一个指针
	this->age = age;
}
void Student::setName(char * name){
	this->name = name;
}
void Student::getAge(){
	return this->age;
}
void Student::getAge(){
	retrun this->name;
}
#include <iostream>
using namespace std;

int mian(){
	//栈区
	Student stu;//调用空参构造函数
	stu.setAge(34);
	stu.setName("我是你爹");
	cout << "name" << stu.getName() << ", age:" << stu.getAge() << endl;
	Student stu1("雄霸",30);//也是在栈区
	
	//在堆区开辟,基本跟上一节一样是new/delete,C++中堆区开辟不要搞C那一套
	//free 不会执行析构函数,malloc也不会调用构造函数
	Student * str = new Student("雄霸",88);
	str ->setAge(99);
	str ->setName("李连杰");
	cout << "name:" << str ->getName() << ",age:" << str ->getAge() << endl;
	
	delete str ;//必须手动释放堆空间的对象
	student2 = NULL;
	return 0;
}

拷贝构造函数

//定义了头文件和实现文件之后执行下面代码
Student s1 = {"张三丰"11};
Student s2 = s1;
cout << s2.name << "," << s2.age << endl;//输出张三丰,11,=号做了什么事情?
// C/C++编译器把s1的值给s2,s1跟s2的内存地址是不一样的,之前我们展示过类似情形
// s1 = s2 ,默认的拷贝函数

Student (const Student & student) {
	//实际上在头文件中我们定义的Student中有默认的拷贝函数,如果我们自己写了的话会覆盖掉旧的
	cout << "拷贝函数" << endl;
	//自己控制拷贝函数,stduent不是一个指针类型,使用的student.name &不是拿对应指针,
	//而是指C函数中对原对象的引用,传递过来时也不用传递指针
	this->name = student.name;
	this->age = student.age-10;
}
//我们是在栈开辟的,当前函数执行完之后会打印两次析构函数,因为有两个对象
Student stu2;
stu2 = s1;//这种方式是不会调用自定义的拷贝构造函数的,但是会调用默认,是有值的。

//下面这种写法压根不会调用拷贝构造函数
Student * s1 = new Student("张三",112);
Student * s2 = s1;
s1->age(99)// 输出99 ,s2指向s1的引用,在堆里只有一个对象,修改的是同一个对象。
cout << "s1的age" << s1->getAge() << endl;
//实际上把

指针常量跟常量指针


int number = 9;
int number2 = 8;
// 常量指针:对指针类型进行const常量修饰
const int * numberP2 = &number;
*numberP2 = 100; //报错,不允许修改常量指针所对应的值
numberP2 = &number2;//OK,允许重新指向常量指针存放的地址

// 指针常量
int * const numberP2 = &number;
*number2 = 100; //OK,允许去修改常量指针存在的地址所对应的值
numberP2 = &number2;//报错,不允许重新指向指针常量存放的地址

//常量指针常量
const int * const numberP2 = &number;
//指针跟地址都不能修改,这点跟我们的认知是一样的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值