c++ 基础知识(1)
2016-03-31 14:21
316 查看
New和Delete
内置类型对象或未提供默认构造函数的类类型对象必须显示初始化int* a = new int; //a未初始化 int* b = new int(); //b初始化为0
delete后,应该将指针赋值为NULL,否则该指针成为“悬垂指针”,悬垂指针是指向曾经存放对象的内存,但该对象已经不再存在了。
C++保证:删除0值的指针是安全的
显示类型转换
调用方式: cast-name(expression)static_cast
编译器隐式的执行任何类型转换
void* p = &d; double* dp = static_cast<double*>p;
dynamic_cast
const_cast
转换掉表达式的const性质
reinterpret_cast
类成员函数的重载
函数名相同,函数的参数不同,返回值可以不同。注意:基于成员函数是否为const,可以重载一个成员函数类的inline函数
编译器会自动展开函数的定义。注意点:一般函数的代码量很小,且该函数会被经常调用。同时,该函数的定义必须被调用它的源文件可见。通常,内联函数的定义是放在某公共头文件中。类的成员使用类声明
只有当类的定义已经在前面出现过数据成员才能被指定为该类类型。如果该类型是不完全类型(即只声明未定义),那么数据成员只能是指向该类类型的指针或者是引用。类的构造函数初始化
构造函数的初始化列表会在构造函数体内语句之前运行。如果没有显式初始化列表,那么对于类类型的成员变量使用该成员变量的默认构造函数初始化。对于内置类型或者是复合类型的成员变量根据对象是否为全局而定。(全局对象则会初始化,局部对象不会初始化)
注意:对于const成员变量或者是引用类型成员变量及没有默认构造函数的类类型成员变量必须在显式初始化列表。
构造函数的隐式转换
一般只带一个参数的构造函数会出现隐式转换,或者是构造函数的第二参数带有默认值class A { public: A() {} A(int a) { num = a; } private: int num; }; A a = 12 //隐式的调用构造函数,再调用复制构造函数 A b(12); //显示的调用构造函数
隐式转换一般会带来不好的影响,最好的处理方法是加上explicit关键字,指定构造函数不能隐式转换。
友元
允许一个类将对其非公有成员的访问授予指定的函数或类static类成员
非static数据成员存在于类类型的每一个对象中。static数据成员独立于该类的任意对象而存在;每个static数据成员与类关联的对象,并不与类的对象关联。static成员函数只能访问static成员变量,不能直接使用非static成员变量。
复制构造函数
调用时间根据另一个同类型的对象显示或者是隐式初始化一个对象
复制一个对象,将它作为实参传给一个函数
从函数返回时复制对象
初始化顺序容器中的元素
std::vector<std::string>(10);//先调用string的默认构造函数,再调用复制构造函数
根据元素初始化式初列表初始化数组元素
A a[] = {std::string("abc"),std::string("bca")}; //首先调用A中接受string形参的构造函数初始化一个临时对象,再调用A的复制构造函数初始化
具体例子
string null_book = "99999";//首先调用接受一个C风格字符串形参的构造函数,再调用复制构造函数 string empty_copy = string();//首先调用默认构造函数,再调用复制构造函数
智能指针
当类中含有指针成员的时候,不重写赋值构造函数,复制构造函数,析构函数的话,很容易使程序崩溃原因: 编译器为我们合成的复制、赋值函数,都只是浅层拷贝,不是深层拷贝(指针指向同一个对象),因此往往会在析构的时候,出现异常。
解决方法1:定义智能指针,引入使用计数概念
class U_Ptr { private: friend class HasPtr; int *ip; size_t use;//使用计数 U_Ptr(int* p) : ip(p) , use(1) { } ~U_Ptr() { delete ip; } }; class HasPtr { public: HasPtr(int*p , int i) : ptr(new U_Ptr(p)) , val(i) { } HasPtr(const HasPtr& orig) : ptr(orig.ptr), val(orig.val) { ptr->use++; } HasPtr& operator=(const HasPtr& rhs) { ++rhs.ptr->use; if(--ptr->use == 0) delete ptr; ptr = rhs.ptr; val = rhs.val; return *this; } ~HasPtr() { if(--ptr->use == 0) { delete ptr; } } private: U_Ptr *ptr; int val; };
解决方法2”实现深层拷贝
class HasPtr { private: int* ptr; int val; public: HasPtr(const int& p, int i) : ptr(new int(p)) , val(i) { } HasPtr(const HasPtr& orig) : ptr(new int(*orig.ptr)) , val(orig.val) { //实现深拷贝 } HasPtr& operator=(HasPtr& rhs) { ptr = rhs.ptr; val = rhs.val; return *this; } };
protected成员
基类的一些成员希望允许派生类访问但是禁止其他用户访问,对于这样的成员应使用受保护的访问标志注意点:派生类只能通过派生类对象访问其基类的protected成员,派生类对其基类类型对象的protected成员没有特殊访问权限。
class Test_base { public: Test_base(){} ~Test_base(){} protected: int pb; private: int kk; /* data */ }; class Test_sun : public Test_base { public: void fun(Test_sun& t, Test_base& base) { t.pb = 1; //派生类对象可以访问基类的protected成员 base.pb = 1;//错误,基类类型的对象不能访问其protected对象 pb = 1; } };
相关文章推荐
- 【C++】《C++标准程序库》小结第十三章-stream(2)
- 关于C++
- c++基础知识---名字空间
- 改进式PID控制以及C语言实现过程
- 2015级C++第6周项目 类的组合、静态存储
- 用C++实现快速排序
- VSCode配置C++编写环境
- PID连续控制算法的表达式以及C语言实现
- 【C++】《C++标准程序库》小结第十三章-stream(1)
- C++中的深浅拷贝问题
- C语言中空格符,制表符,换行符详解
- c++之派生类访问基类的友元函数
- C/C++中指向指针的指针传递函数
- 函数
- 牛客网-拼接最小字典序问题
- 『C++ Primer学习笔记』Chapter 1
- C++Builder 2010 生产的EXE软件在没由安装C++Builder 2010的电脑上运行的方法
- C++ _类模板
- 第七届蓝桥杯省赛C\C++B组题目之四平方和
- C语言实现时间的加一天或者减一天