C++基础知识

什么是命名空间?

using namespace std;
类似于java中的包名,主要是为了解决多个模块间命名出冲突的问题

带默认形参的函数

int  add(int a =4,int b =5){
    return a+b;
}
cout << add() << endl; //9

函数模板

C++和java一样都有函数的重载,函数重载可以处理多种类型,同一个方法名,但依然需要分开定义,如果可以让他代码更精简一点,模板化就更好了,为此C++提供了函数模板这一机制,可以大大提高函数的通用性(自我感觉像泛型)

template<class 类型名1,class 类型名2>
返回值 函数名(形参表列) 模板参数表
{
   函数体
}

内联函数

通过在函数上添加inline关键字,在编译的时候,把函数代码插入到函数调用的地方, 就像普通的程序执行代码一样

类的定义

class Sts{
public://访问修饰符跟java类似
    int a;
    char name[100];
    int socre;
    int print();
};//注意这个分号
int Sts::print(){//在类外定义函数体,在类外定义函数体的需要类名加上::域限定符
     cout<<a<<"/"<<name<<"/"<<socre<<endl;
    return 0;
}

对象的建立和使用

对象创建

int *a=  new int;//动态分配一个int类型的内存空间;
delete a;//释放内存;    
//分配10个int数据空间
int *aa= new int[10];
delete []aa;

对象指针

Sts *p;
Sts s;    
s.a=100;
s.socre=200;
strcpy(s.name, "xin");    
p=&s;
p->print();

对象引用

Student A;
Student &Aq=A;

友元函数

利用友元函数(声明加上friend),把外部的函数声明为友元类型,赋予它可以在类外访问类的私有变量,友元函数既可以是全局函数,也可以是其他类的成员函数,不仅如此,友元还可以是一个类,叫做友元类

虚基类和虚基类的使用

虚基类就是在继承的public之前加上virtual关键字,只要加上这个关键字派生类就维护一份基类对象,避免在多继承情况下多次拷贝,出现歧义

#include <iostream>
using namespace std;
class CBase
{
public:
	int a;
public:
	CBase(int na)
	{
		a=na;
		cout<<"CBase constructor! "<<endl;
	}
	~CBase(){cout<<"CBase deconstructor! "<<endl;}
};
//派生类1(声明CBase为虚基类)
class CDerive1:virtual public CBase
{
public:
	CDerive1(int na):CBase(na)
    {
		cout<<"CDerive1 constructor! "<<endl;
	}
	~CDerive1(){cout<<"CDerive1 deconstructor! "<<endl;}
	int GetA(){return a;}
};
//派生类2(声明CBase为虚基类)
class CDerive2:virtual public CBase
{
public:
	CDerive2(int na):CBase(na)
	{
		cout<<"CDerive2 constructor! "<<endl;
	}
	~CDerive2(){cout<<"CDerive2 deconstructor! "<<endl;}
	int GetA(){return a;}
};
//子派生类
class CDerive12:public CDerive1,public CDerive2
{
public:
	CDerive12(int na1,int na2,int na3):CDerive1(na1),CDerive2(na2),CBase(na3)
	{
		cout<<"CDerive12 constructor! "<<endl;
	}
	~CDerive12(){cout<<"CDerive12 deconstructor! "<<endl;}
};
void main()
{
	CDerive12 obj(100,200,300);
	cout<<" CDerive12:a = "<<obj.a<<endl;
	//得到从CDerive1继承的值
	cout<<" from CDerive1 : a = "<<obj.CDerive1::GetA()<<endl;//300
	//得到从CDerive2继承的值
	cout<<" from CDerive2 : a = "<<obj.CDerive2::GetA()<<endl;//300
}

虚函数

类似于java中的多态,在运行时判断属于哪个类型,执行什么函数

  • 虚函数不能是静态成员函数,或友元函数,因为他们不属于某个对象
  • 内联函数不能运行中动态指定其位置,及时虚函数在类内定义,编译时,仍将看做非内联
  • 构造函数不能是虚函数,析构函数可以是虚函数,而且通常声明为虚函数
class A{
public:
    virtual void print(){
        cout<<"A"<<endl;
    };
};
class B : public A{
public:
    void print(){
        cout <<"B"<<endl;
    }
};
int main(int argc, const char * argv[]) {
    A a;
    a.print();
    B b;
    b.print();
    A *p;
    p=&b;
    p->print();
    A &pp=b;
    pp.print();
    return 0;//ABBB
}

文件读写

int main(int argc, const char * argv[]) {
    char data[100];
    //读文件
    ifstream in;
    in.open("/Users/renxiaohui/Desktop/test.txt");
    in>>data;
    cout<<data<<endl;
    in.close();

    //写文件
    ofstream out;
    out.open("/Users/renxiaohui/Desktop/test1.txt");
    out<<name;
    out.close();
    return 0;
}

智能指针

  • unique_ptr:专属所有权,unique_ptr 代表的是专属所有权,即由 unique_ptr 管理的内存,只能被一个对象持有。所以unique_ptr 不支持复制和赋值,make_unique
  • shared_ptr:共享所有权,即多个 shared_ptr 可以共享同一块内存
  • weak_ptr:可共享的未来的所有权,weak_ptr 不会增加引用计数,因此可以打破 shared_ptr 的循环引用
//unique_ptr
//为动态申请的资源提供异常安全保证
//返回函数内动态申请资源的所有权,函数结束后自动释放内存
int main() 
{
    auto fPtr3 = std::make_unique<int>();
    unique_ptr<int> pInt(new int(5));
    unique_ptr<int> pInt2 = std::move(pInt);    // 转移所有权
    //cout << *pInt << endl; // 出错,pInt为空
    cout << *pInt2 << endl;
    unique_ptr<int> pInt3(std::move(pInt2));
}