1、C++第一个程序
示例:
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
cout << "hello World" << endl;
return 0;
}
2、C++访问控制
属性 | 权限 |
---|---|
private | 私有的,只能在类的内部被访问 |
public | 公有的,能在类的外部被访问 |
示例:
#include <iostream>
using namespace std;
class person
{
private://表示私有的,只能在person类内部进行访问
string name;
int age;
public://表示公有的,可以在person类的外部被调用
void printf_info(void)
{
cout << "name = " << name << ", age = " << age << endl;
}
};
int main(int argc, char** argv)
{
person per2("Bruce", 16);
per2.printf_info();
return 0;
}
3、C++构造方法
class person
{
private:
string name;
int age;
public:
person()//无参构造方法
{
cout << "调用无参构造方法person()" << endl;
}
person(string name, int age);//有参构造方法
{
cout << "调用有参构造方法person()" << endl;
this->name = name;
this->age = age;
}
};
4、C++函数重载
函数重载就是函数名相同,函数的参数不同,包括顺序不同也认为是不同。以下定义了一个person类,里面的构造函数分别有无参构造函数和有参构造函数,其实就是函数重载的表现。
class person
{
private:
string name;
int age;
public:
person()//无参构造方法
{
cout << "调用无参构造方法person()" << endl;
}
person(string name, int age);//有参构造方法
{
cout << "调用有参构造方法person()" << endl;
this->name = name;
this->age = age;
}
};
5、C++命名空间
命名空间用于解决函数名相同时编译器不知道应该调用哪一个函数的问题。
假设团队里的A成员写了一个printf_verson函数。团队里的B成员也写了一个printf_verson函数。
这时候如果调用printf_verson函数,编译器就不知道要调用哪一个函数了,因此就需要使用命名空间将函数区分开来。
示例:
#include <iostream>
using namespace std;
namespace A {//将里面的代码全部归类到A这个命名空间里面
void print_verson(void)
{
cout << "A V1.0" << endl;
}
}
namespace B {//将里面的代码全部归类到B这个命名空间里面
void print_verson(void)
{
cout << "B V1.0" << endl;
}
}
int main(int argc, char** argv)
{
//print_verson();//直接调用会出错,因为编译器不知道要找哪一个print_verson
A::print_verson();//编译器就知道,你是要调用A命名空间里面的print_verson
return 0;
}
6、C++程序结构
假设团队需要A成员实现一个person类,则一般情况下,程序将会分为
main.cpp
person.cpp
person.h
person.h文件用于定义person类,给别人看的,如下:
#pragma once
using namespace std;
namespace A {//将里面的代码全部归类到A这个命名空间里面,代表是A这个成员写的代码,当然也能写其它的标识符
class person
{
private:
string name;
int age;
public:
person(string name, int age);
void print_info(void);
};
}
person.cpp是person类的实现,如下:
#include <iostream>
#include "person.h"//注意使用的是""号,表示在当前路径下先查找头文件
using namespace std;
namespace A {//将里面的代码全部归类到A这个命名空间里面
person::person()
{
cout << "调用无参构造方法person()" << endl;
}
person::person(string name, int age)
{
cout << "调用有参构造方法person()" << endl;
this->name = name;
this->age = age;
}
void person::print_info(void)
{
cout << "name = " << name << ", age = " << age << endl;
}
}
main.cpp是person类的调用,如下:
#include <iostream>
#include "person.h"
using namespace std;
using namespace A;
int main(int argc, char** argv)
{
person per2("zhangsan", 16);
per2.print_info();
return 0;
}
7、C++ new/delete/析构函数
使用new进行动态内存分配时,使用完成以后需要用delete将内存释放掉。
析构函数的作用就是在对象被释放之前,系统自动调用析构函数,一般用来做内存的释放操作。以下是经典示例:
person.h
#pragma once
using namespace std;
namespace A {
class person
{
private:
char *name;
int age;
public:
person();
person(char *name, int age);
~person();//析构函数
void print_info(void);
};
}
person.cpp
#include <iostream>
#include "person.h"
using namespace std;
namespace A {
person::person()
{
this->name = NULL;
cout << "调用无参构造函数person()" << endl;
}
person::person(char* name, int age)
{
cout << "调用有参构造函数person()" << endl;
this->name = new char[strlen(name)+1];//使用动态内存分配
strcpy(this->name, name);
this->age = age;
}
person::~person()
{
cout << "调用有析构函数" << endl;
if( this->name != NULL )
delete this->name;//将占用的内存释放
}
void person::print_info(void)
{
cout << "name = " << this->name << ", age = " << this->age << endl;
}
}
main.cpp
#include <iostream>
#include "person.h"
using namespace std;
using namespace A;
void test_fun()
{
person per((char*)"zhangsan", 16);
per.print_info();
/* 因为per是局部变量,所有在函数运行结束以后就释放了,释放之前,系统会调用析构函数进行内存释放 */
}
void test_fun2()
{
person *per = new person((char*)"lisi", 10);
per->print_info();
delete per;
/* 因为per指针使用new进行动态内存分配,因此需要手动释放 */
}
int main(int argc, char** argv)
{
cout << "定义zhangsan之前" << endl;
test_fun();
cout << "定义zhangsan之后" << endl;
cout << "定义lisi之前" << endl;
test_fun2();
cout << "定义lisi之后" << endl;
return 0;
}
8、C++ 默认拷贝构造函数
int main(int argc, char** argv)
{
person per1((char *)"zhangsan", 16);
person per2(per1);//将per1的内容进行值拷贝到per2,也就是说per1和per2的name都是指向同一片内存,当对象销毁以后,同一片内存name就会被析构函数释放两次,就带来了问题
per2.print_info();
return 0;
}
9、C++ 自定义拷贝构造函数
因为默认的拷贝构造函数是值拷贝,引入了内存重复释放的问题,因此需要自定义拷贝构造函数,来解决此问题
person::person(person &per)
{
this->age = per.age
this->name = new char(strlen(per.name)+1);
strcpy(this->name, per.name);
cout << "调用自定义拷贝构造函数person(person &" << endl;
}
10、对象的构造和析构顺序
按运行时定义对象的顺序调构造函数,静态对象只调用一次构造函数,全局对象在main函数之前进行构造
11、继承时的构造和析构顺序
先调用父类的构造函数,再调用子类的构造函数。析构顺序和构造的顺序相反。
要调用对象成员的其它构造函数
12、静态成员
using namespace std;
class person
{
private:
static int count;//用于统计person被创建的个数
char *name;
int age;
public:
person(){}
person(char *name, int age){}
~person(){}
void print_info(void);
static int get_count(){return count;}//因为count是private的,所以需要用函数暴露出去
};
/* class 里面虽然有static的成员变量,但是只是一个模版,还没有分配内存呢,要使用下面的方法给它分配内存空间,并且要给他赋值初始化 */
int person::count = 0;
/* 如何调用静态成员函数? */
int main(int argc, char** argv)
{
person::get_count();//直接通过类来调用静态成员函数
return 0;
}