c++易错点总结

c++易错点的话还挺多
1.关于调用拷贝构造函数
(1)使用一个已经创建完毕的对象初始化一个新的对像

  p1(p2)

(2)值传递的方式给函数参数传值

 #include<iostream>
		using namespace std;
		class A{
			public:
			A(int c)
			{
				a=c;
			 } 
			A(A &p)
			{    
				cout<<"拷贝构造函数!"<<endl; 
			  a=p.a;
			 } 
			 ~A()
			 {
			 	cout<<"析构函数"<<endl; 
			 }
			 private:
			int a;
		};
		void text(A a)//实参传递给形参的时候会拷贝一个新的函数
		{
			
		}
		int main()
		{
			A a(1);
			text(a);
			return 0;
		}
		    

(3)值方式返回局部对象

#include<iostream>
	using namespace std;
	class A{
		public:
		A()
		{
			cout<<"默认构造!"<<endl; 
		 } 
		A(A &p)
		{    
			cout<<"拷贝构造函数!"<<endl; 
		  a=p.a;
		 } 
		 ~A()
		 {
		 	cout<<"析构函数"<<endl; 
		 }
		 private:
		int a;
	};
	A text()
	{
		A a; 
		return a;
		
	}
	int main()
	{
		A b=text();
		return 0;	
	}

2.对于c++t源代码的关键字所有的template可以用class替换然而有些class却不能被template替换
3.通过继承可以建立类族
4.关于类模板

            #include<iostream>
   			#include<string>
			using namespace std;
			template<class NameType,class AgeType=int>//类模板在模板参数列表中可以有默认参数 
			class person{
				public:
				person( NameType a,AgeType b){
					this->age=b;
					this->name=a;
				}
				void show()
				{
					cout<<age<<endl;
					cout<<name<<endl;
				}
				NameType name;
				AgeType  age;
			};
			void text()
			{
				person<string,int>p1("111",1);//类模板没有自动类型推理
				p1.show();
				
			}
			int main()
			{
			    text();
				return  0;	
			}
			                        

5.定义类动态对象数组时其元素只能靠调用该类的默认构造函数初始化
6.类模板不能派生,类模板实例化的对象叫量产(模板类),且量产的类之间没有任何关系
7.关于动态特性
在绝大多数情况下, 程序的功能是在编译的时候就确定下来的, 我们称之为静态特性。 反之, 如果程序的功能是在运行时刻才能确定下来的, 则称之为动态特性。C++中, 虚函数,抽象基类, 动态绑定和多态构成了出色的动态特性。
8.派生类子对象就是派生类的数据成员中有其他类的对象,基类子对象是基类数据成员中有其他类的对象
9.只有公有的继承下派生类是基类的子类型
10.关于子类型:

class base
		{
		public:
			void print()const{cout<<"base::print()"<<endl;}
		};
		class derived:public base
		{
		public:
			void fun();
		};

派生类derived从基类base公有继承。因此类derived是类base的一个子类型,类derived具备类base中的操作,或者说类base中的操作可以被用于操作类derived的对象。
注:子类型关系具有传递性。子类型关系可以传递,但是不可逆。

公有继承可以实现子类型关系。通过公有继承,派生类得到了基类中除了构造函数、析构函数之外的所有成员,而且可访问成员的访问控制属性也和基类完全相同。这样,派生类对象就可以作为基类的对象使用,但它只能使用从基类继承的成员。

具有子类型关系的基类和派生类的对象之间满足如下赋值兼容规则:

(1)公有派生类的对象可以赋值给基类的对象,即用公有派生类对象中从基类继承来的成员,逐个赋值给基类对象的成员。
例: derived d;
base b;
b=d;
(2)公有派生类的对象可以初始化基类的引用。
例: derived d;
base &ref=d;
(3)公有派生类的对象的地址可以赋值给指向基类的指针。
例: derived d;
base ptr=&d;
11.转换函数:
他是一种特殊的类成员函数,转换函数必须是成员函数,他的声明不能指定返回类型和参数列表
12.静态成员函数不能声明为虚函数
13.看一道题
9.下列语句错误的是( B )
A.char name[5]=“John”;name[2]=‘a’; Bchar
p=“John”;p[2]=‘a’;
C.char name[5]=“John”,*p=name;p[2]=‘a’;
D.char name[5]=“John”,*p=&name[2];*p='a;
解析B中你构建了一个字符串数组,你把J的首地址返回给了p,但是编译器会认为你的p是一个字符指针而不是字符数组指针所以p[2]无法使用
如果想让p[2]能被使用可以如下:

#include<iostream>
using namespace std;
int main()
{
	char arr[10];
	for(int i=0;i<10;i++)
	{
		cin>>arr[i];
	}
	char *p=arr;//把一个已知数组的首地址给它;
    cout<<p[2];
	return 0;
	
}

14.c++每个类的成员函数隐含的第一个参数的参数名为this指针,指向对象自己;
15.关于枚举类型,首先它不是基本数据类型,以下面的例子说明:

enum day{monday,tuesday,wednesday,thursday,friday=2
};
         

枚举类型的第一个常量默认值是0,而且依次加1,枚举类型允许彼此的值相等,虽然枚举类型是整形类,但是不允许使用整数直接给枚举变量赋值也不允许与整数进行运算,只可以与整数进行比较;
16.(1)const int a和int const a;完全等价其值后续操作不能改变
(2)const int *p与int const *p;完全等价作用均为声明指向整形常量的整形指针p,指针指向内存空间的内容不可以被修改但指针的指向可以被修改;
(3)int *const p;p所指内存空间的内容可被修改但p指向固定不可以被修改;
17.位运算(化成八位二进制)
(1)~:按位求反,把0变成1把1变成0;
比如二进制1001011
变成0110100
(2)<<:2(2代表向左移动两位)左移,向左移动右边补0,>>效果和它类似;
(3)&:两个二进制1——1得1剩下都是0;
(4)^:相同得0,不同得1;
16.0x+数十六进制,0+数字八进制,e后面不能跟小数
17.c++存储类别,auto,register,static,extern,mutable;
18.声明逻辑类型的变量所用的关键字是bool;
19.用于控制输入输出格式的枚举常量中代表十进制八进制十六进制的分别是;dec oct hex
20.关于内联函数:
(1).不能存在任何形式的循环语句
(2).不能存在过多的条件判断语句
(3).函数体不能过于庞大
(4).不能对函数进行取址操作
内联函数和宏定义基本类似
优点是减少函数得调用开销,提高运行效率;
缺点是用时间换取空间,用到内敛的时候都要重新编译;
内联函数可以重载;
另外内联函数和代码运行的快慢无关;
21.内部函数和外部函数:
内部函数又被称为静态函数,只能是本文件使用用static定义
外部函数
22.(1)strcmp(a,b)返回值如果a,b相同返回0,否者返回非0整数;
(2)字符串大小比较,从第一个字符开始比较大小,直到比较出大小为止;
23.数组名代表首地址且不可以改变,比如a[10],不能a=a+1,a叫做地址常量;
数组名作为函数参数,主调函数和被调函数共用一段存储单元

发布了6 篇原创文章 · 获赞 8 · 访问量 357

猜你喜欢

转载自blog.csdn.net/qq_45737068/article/details/103810079