C++基础语法总结

这几天C++语法考试,记录一下:html

 

a第一章:算法

1,面向对象程序设计的有点:数组

实现对现实世界客体的天然描述。app

可控制程序的复杂度。ide

可加强程序的模块性。函数

可提升程序的重用性。this

可改善程序的可维护性。spa

 

 

第二章:设计

1,cin -> stdin; cout -> stdout; cerr->stderr;clog->stdprn,cerr和cout的区别就是他不可以被重定向。指针

2, 命名空间的声明 namespace mfc {int inflag;} 同一个命名空间能够定义屡次。

using 用多了会冲突。

3,cin>>x>>n,这个输入到x,n主要是经过空格来隔开的。也是经过空格表示结束。

4,dec 十进制, oct八进制,hex十六进制,cout<<hex<<i<<endl;一旦进入这个状态就不能改变了。例如,cout<<hex<<i<<endl; cout<<i<<endl; 两个都是十六进制。

5,setw若是不够大小的话不起做用,若是比原来的大的话从左边填充。setw是一次性的,就是说若是输出了,就不会见效了,必须从新来。例如,cout<<setw(3)<<3456,这个不会扩大,而cout<<setw(7)<<3456就会左边填充空格,以后cout<<3456又回到wide = 0的默认值了。这个东西是iomanip文件中的,须要include <iomanip>

6,setprecision()这个在double地时候是表示留下几位。例如,33.33 setprecision(2), 33.3,若是有fixed,就是小数点固定,就表示小数点后面几位的。例如,33.3333 fixed + setprecision(2) 为33.33 表示小数点以后的留下几位。

7,ifstream fstr(path) ofstream istr(path)

8,const int* a 这个表示所指向的内容不会变。int* const a 表示指针a不能变。

9,float j = static_cast<float>(i). const_cast<int> 把const转化成为不一样的。

if(typeid(*base) == typeid(Derived1)) {

    Derived1 *derived1 = static_cast<Derived1*>(base);

    derived1->showOne();

}

static_cast和dynamic_cast就是都是经过是基类转化成为派生类。可是static就是强转化,而dynamic_cast是弱转换。若是失败会跑出bad_cast的异常。

若是device& x, dynamic_cast<deviceBase&>(x)....须要注意引用的应用。这里面须要注意的是dynamic_cast<D> D 必定是引用和指针。

reinterpret_cast用于不一样类型的转换。 

10,bool的地方也能够用Int是否等于0来判断。-1也是true。

11,string是以NULL为结尾的。string s4(10,'X'); string s3 = s2; int 转化成为string 用<sstream>中的stringStream,由于是流.例如:

string str;

stringStream strStream;

int i = -1;

strStream<<-1<<endl;

strStream>>str;

cout<<str<<endl;

 

12,遍历文件夹getline

#include <string>

#include <file>

using namespace std;

 

int main(char* args[])

{

string str;

ifstream input("C:\\source.txt");

ofstream output("C:\\dest.txt");

while(getline(input,str))

{

output<<str;

}

input.close();

output.close();

}

这里须要注意,file的空间和getline的返回。

 

13,erase(开始位置,长度);insert(插入位置,插入的字符串);replace(替代位置,子窜大小。子串。),swap(字串),find("",startPos), 字符串支持 == > < != 这样的操做。

 

14,int main(int argc,char * argc[]){...}

15, 引用,通常都是用于参数传递的时候用,这样可以对这个参数进行修改。不能然会局部变量的引用。

16,inline函数的限制:

a,不能包括复杂的结构控制语句(while, switch)。

b,不能包括内联函数自己。

c,不能是直接递归。(本身内部还调用本身的函数)

17,inline和宏的区别:

a,宏是预处理器进行替代,而inline是编译实现的。inline有更强的约束性。

b,inline函数是真正的函数,是准寻函数类型和做用与规则。

注意:类中的inline函数通常都是在.h文件中直接定义。

18,函数签名不包括返回值,因此不能只看返回值。

19,函数的默认参数必须从右边开始。

20,

 

第三章:

1,C++中class 的默认的做用域和private是同样的。而struct的默认的是public同样的。

2,inline在类里面,若是在.h生成的就是内联函数。若是是分开定义的,那么就在.h定义这里面加上inline字符就能够了(注意cpp不要加。)

3,

成员函数+const 就是让属性值不要减小。 例如:GetValue() const{return this->a;} 这里a不能有。

并且这里面不可以调用non_const的成员函数。

4,若是函数返回类型采用const的话,那么,只能赋值给一个const类型的局部变量。

5,

对象数组,当调用对象数组的时候,会默认调用每一个对象的构造函数。C ar[1000] 会调用1000次构造函数。若是没有够着函数,会默认生成一个默认的。

若是有了一个公有的,就不会生成默认的。

默认的够着函数,里面的类成员不能被初始化。

6,

拷贝构造函数:Person(Person& person)和Person(const Person& person),拷贝构造函数能够有多个参数,可是这些参数必须有默认值。

当函数中有一个属性指向了动态存储空间的时候,应该调用拷贝构造函数。默认的只是直接赋值,这样,两个对象的指针就指向同一个对象了。若是命名了拷贝构造函数的话,就不会有默认的了。

这个时候,若是把这个拷贝构造函数放在私有,这样就禁止了拷贝构造函数。

7,转型构造函数,里面要用到一个explicit。但是实现隐形转换。

8,初始化够着函数列表。Person():x(1),y(0),并且const只能经过这来初始化。

9,类静态成员的声明,int C::s = 0;并且若是没有用static标明,不可以在函数中声明。

10,const 对象不可以调用成员函数,主要是由于这样可以改变这个类里面的值。

 

第四章:

1,C++ 支持多重继承,就是一个类能够同时继承多个类。

2,经过using能够在子进程中改变基类的控制范围。例如:

class BaseClass

{

public:

BaseClass(int value);

int GetValue();

void SetValue(int i );

private:

int value;

}

class derivedClass: public baseClass

{

public:

DerivedClass(int a ,int b):BaseClass(a),valueB(b);

void SetValue(int i);

private:

using baseClass::GetValue;

int valueB;

}

3,若是继承以后新成员(成员函数,成员变量)名称(只同名就能够)和基类的同名,他将会覆盖这个老成员函数。其实也无所谓隐藏,BaseClass::SetValue()和DerivedClass::SetValue()来区别的就好了。

4,在公有继承的方式下,保护成员是可以被子类看到的。

5,构造函数和析构函数是不可以被继承的。当派生类没有本身的构造函数的时候,会直接调用父类的默认构造函数。若是没有声明,在调用本身的初始化构造函数的时候,调用父类的初始化构造函数。

例如上面的类:若是子类没有构造函数而父类有,这样的话,父类的构造函数必须有默认构造函数。其实就是说,若是要是显示调用了基类的构造函数的话,就不须要了。若是要是没有显示,须要父类有一个默认构造函数,子类会调用。

6,析构函数的工做和构造函数的调用顺序正好相反。并且,析构函数每一个类至多只有一个。

7,类成员初始化的顺序取决于他在被继承时所说明的顺序,并不是初始化队列的顺序。

8,多重继承的时候,若是两个基类有同名的函数,这样的话就会发成冲突会出错。

多继承的构造函数顺序,基类的构造函数先被调用,数据成员所在类的构造函数次之,最后指向派生类的构造函数。这个其实就是由于构造函数的时候先执行父类的,而后才是属性复制,而后才是当前的构造函数。

9,虚基类,当多重继承的时候。例如:

class C : D1,D2

{

 

}

class D1: B

{

 

}

class D2: B

{

 

}

class B

{

public: int x;

}

这个时候当生成C的时候,会生成两个B class的副本(内存里面是两个B的对象),这个时候,若是 C.B::x = 2; 是有问题的,由于这个时候并未指明是哪一个B 的副本。并且,当你调用C.x的时候也有二意性。C.D1::x 和 C.D2::x不是一个值。可是,若是上面的全都是弄成虚基类。也就是以下:

class D1 : virtual B

class D2: virtual B

这个时候就只有一个副本了,C.B::x =2 只有一份,不会有歧义。C.x也是。还有虚基类的构造函数最早调用。

10,继承分为三种继承:

公共继承,公有的-》公有,私有的—》不可访问,保护的-》保护

私有继承,公有的-》私有,私有的—》不可访问,保护的-》私有

保护继承,公有的-》保护,私有的—》不可访问,保护的-》保护

11,类型适应:派生类的对象,引用,指针均可以赋值给基类的。

 

第五章:

1,虚函数这个东西,须要在基类上面定义virual函数,子类若是不定义也能够(不定义回去找同名的),定义更好。虚函数的主要目的在于动态绑定,若是不是虚函数,那就是对象是什么就调用什么,而若是是虚函数,就是调用真正的。若是在外面定义的函数,只须要在生命时候加上virtual就能够了。

例如: Base a; Derive b;

a = b;

a.print(); 若是print是虚函数,调用的就是b.print,若是不是调用的是a.print。

如今有这么一个例子:

Class Base{ 

void Act1(){Act2();}

void Act2(){cout<<"ori act2"<<endl;}

}

class Derive:public Base

{

void Act2(){cout<<"dest act2"<<endl;}

}

 

Derive b; b.Act1(); 输出是? 

 

ori act2

 

若是把Act2 变成虚函数,这个时候结果就是 dest act 

 

这里主要是由于这个时候this指针已经多态了,你能够把this当作 Ori* source = new Derive();

2,析构函数能够是virual的。只要加了virtual,派生类的就都不须要加了。vitual析构函数的做用是delete 子类的时候(可是这时候是动态绑定,内容是子类的,表表面是基类的),会调用子类的析构函数,以后还会调用父类的析构函数。若是要是没有virtual,动态绑定的时候,对不会调用子类的析构函数。若是是其余函数,若是派生来加上了virual就是说它如今也是虚函数,下面的人能够覆盖。

3,静态成员函数不能够是虚函数。

4,重载:就是同一个类,两个不一样样签名的函数。---》编译绑定

覆盖:基类子类,虚函数,两个一样签名(不含返回值)的函数。---》动态绑定

隐藏:基类子类,不是虚函数,函数名字相同就行。 ---》编译绑定

若是虚函数,若是不产生覆盖(在只有函数名字相同的时候),就会产生隐藏。

5,纯虚函数主要是的写法是: virtual void open() = 0; 又纯虚函数的类不可以产生对象。

6,在#include <typeInfo> 中typeId()

也就是typeid(对象,引用,指针) == typeid(类,引用,指针) 例如class A;... A a; if(typeid(a) = typeid(A)){cout<<"TRUE"<<endl;}

7,动态函数中调用虚函数,搜现实调用本身类实现的,若是本身类没有实现,就调用基类的虚函数。不会调用其余派生类的。

 

第六章

1,不能被重载的运算符:?: . * ::;除了=以外,其余的均可以被派生类继承。操做符重载不改变优先级和集合率。

2, 顶层操做符重载在定义的时候必须就不是相类成员同样了。他就没有默认的类对象当作参数。并且必须明确的指出来。

例如,C operator+(const C&c, const C& c2) 这个主要就是 Cresult = c + c2;

而且,对于顶部操做符重载,咱们须要用到一个自定义个类。若是要是没有的话,区分不了。

这样的操做都是顺序的,例如:C operator[](Point& s , int i)就是 s[i]这个样的一个东西。是有前后顺序的。

对于二次型操做符,与使用类成员函数相比,只要定义了可转型的构造函数,使用顶层函数进行重载是能够不用在意左右两边的。若是用类的话,第一个参数必须是类对象。(恶心:()

3,友元函数其实很简单,就是在一个类里面的方法的前面加上friend,放在public,protect,private均可以,反正不是这个类的函数。这样在外面定义的时候不须要加上friend,这个时候这个函数就可以访问这个类的私有和protect的变量的。例如:

class A

{

public:

void Print();

friend void PrintOut();

friend B::PrintA();

friend C;

private:

int a;

}

 

class B

{

public: 

void PrintA();

}

 

class C

{

public:

void PrintA()

{

cout<<a<<endl;

}

}

 

void B::PrintA()

{

cout<<a<<endl;

}

 

void PrintOut()

{

cout<<a<<endl;

}

如上面,友元能够为一个类,一个类的成员函数,一个顶层函数。可是,咱们只建议在顶层操做符的时候使用。

3,>>的操做符重载,这里通常第一个参数通常都是istream的引用。返回的也是。

()函数操做符的重载,double operator()(double x,double y) const { return x*2 + y;} ,这个就是f(1.5,3.2);

counter operator ++(); 前缀操做符 counter operator++ (int); 后缀操做符,后面的int就是为了代表是后缀操做符。

 

第七章

1,模板这东西实际上是编译程序会根据函数调用的实际状况把T所表明的类加载进去。因此,若是T出了问题编译是不能经过的。

函数模板在应用的时候,不要用<>来制定类型,他会直接经过传入的参数类型直接定义T的类型。例如:

template<class T>

T Sum(T a,T b)

{

return a + b;

}

void main()

{

int sum = Sum(1,3);

}

2, 模板这个东西的格式比较好玩,就是生命的时候呢,类用永远和《T》不要紧,可是在定义的时候<T>必定要制定了。并且,在它用于当作做用域的时候也须要制定。这个函数就不是了,模板函数不须要指定。例如,

template<class T, int i>

class A

{

public:

T a;

T Get_a_Value();

}

 

template<class T,int i>

T A<T,int i>::Get_a_Value()

{}

 

void main()

{

A<int,5> a;

int i = a.a;

}

并且还有一点须要注意,就是当你声明template的类时候,这个类的方法好像必须定义在.h文件当中。

3,这里还有一个值得注意到地方,不一样T的template类是彻底不一样的两个类,例如上面的A<int,3>和A<int 4>;A<double,1>和A<int,1>;不是一个类型,因此他们不可能拥有同一个基类,同一个静态变量。而A<int,4>和A<int,4>的对象就是同样的。

4,STL包括容器,算法,迭代器,函数对象,适配器,配置器。

5,迭代器就是一个封装了的指针,指向一个容器的每一个数值。他重载了*符号,访问他说指向的值。还有他重载了++运算法。能够移动。

有向前迭代器和向后迭代器,向前就是++向前,而向后就是++向后移动。还有,他有const不const,若是是const代表不可以改变iterator的值。

6,list -> 双向链表 

vector -> 能够伸缩的数组

deque -> 两端进行有效插入删除的数组。

set 不含重复值的集合

map 键值不能够重复

multiset 容许重复值的set

multimap 容许重复键值的map

 

vector 适合在尾部插入删除的操做,deque适合两边插入删除的操做。

list不可以经过下标访问。

 

7,stack,queue, priority_queue: stack,queue默认派省委deque;priority_queue默认为vector

stack<char> s;默认 stack<char,vector<char>> s

 

8,bitset记录二进制,bitset<8> bs  --8位0 bitset<8> bs(9) --8位表示9

 

其余积累:

1,C++中没有finally,必须用try catch来搞定,或者用对象控制。

2,C++中最好不要用两层的调用。例如:a.b.c.size();

3,类的参数初始化在.h文件中就行。

4,typeid 是<typeinfo> 命名空间的。 dynamic<t>这个T为目的端的。typeid只对有virtual的虚类才有做用。也就是 polymorphic class type。http://www.cplusplus.com/reference/std/typeinfo/type_info/

5,vector 中的=就是copy。

6, 在C++的.h引用中,用#ifndef classFlag; #define classFlag #endif的方法,这个防止类重复定义。

7,一个类的私有函数其实就是一个类的private,是针对于类而言的,并非针对于对象而言的。例如,拷贝构造函数中就能够在当前的构造函数中,调用另外一个同一个类对象的私有成员变量。例如:

A(const A& a)

{

    this.num = a.num; //num是A类的私有成员

}

8,函数中char * a = "helloworld" 这个字符串是放在堆里面的。char a[] = "helloworld"是放在栈里面的。

9,explict 是用来避免隐式转换的。不少时候构造函数肯能会有隐式转换功能。例如:

A(int a);

A a(0); a = 5; 其实就是 A temp(5); a = temp; ~temp();

若是不想隐式转换,就必须用explicit。上面为explicit A(int a)就能够了。

 http://wenku.baidu.com/view/2d94f7264b35eefdc8d3334d.html

10,extern 的做用:他能够用于修饰变量和方法,它的主要做用是防止在一个.h文件中定义的一个对象,而在另外一个文件中须要用extern链接。若是没有extern这个时候编译会出错误。由于他们都是先编译以后链接,若是编译以后再链接,就会出现同名的错误。

例如:a.h: int a; b.h extern int a 这个时能够的,方法也是,可是若是要是没有extern 链接的时候就会冲突

extern 'C' 这个主要做用就是为了让C++引用C中的方法的变量,由于C++ 有的时候编译的C是不同的。例如,C++有函数重载的概念,而C老是没有的。因此int find(int a,int b)在C++ 编译以后会是 _find_int_int(注意没有考虑返回值),而C中的只有_find。这个时候若是不用extern,就会出现找不到函数的现象。

因此,须要在引用.h文件时候。extern 'C'{#include 'ac.h'},或者单独定义函数。

10,函数指针int* (*function)(int a, int b).

11, int const* p 和const int* p是同样的都是指向一个指向一个const int的指针,而int * const p才是指针不会变化的那种。 const int* const p呢 ?

12,UTF-8 3bytes UTF-16 2bytes。

13,__thiscall __cdecl这两个主要是标明当前这两个方法的主要类型,thiscall是类的成员函数,他在应用函数指针会出现问题,由于thiscall的函数基本都是经过类以后找函数表实现的,它的内部机制和普通的函数指针有所不一样。而cdecl是回调函数,这个有一点好处就是函数指针能够直接引用。通常外围函数,和类的静态函数是cdecl的。这里须要注意若是你须要应用thiscall,就须要用到mem_fun和mem_fun_ref这两个STL类,他们的主要做用就是转化的。详细请看http://apps.hi.baidu.com/share/detail/4994454

14,C++存储区中分为堆,栈,静态存储区。通常常量是放在静态存储区里面的。

15,动态连接库是在进程启动的时候加载的。

16,只有指针才能动态绑定,对象是不行的。

相关文章
相关标签/搜索