typename 是表明后面的为类型名的标识符,类内不以typename修饰的类型名,均视为一个值。
class Example
{
typedef int SubType;
//...
};
typename Example::SubType * ptr; //返回int型指针
Example::SubType * ptr; //解释为相乘
//typename 替换template中的calss
template class Example;
template 的用法
template
class MyClass
{
private:
T value;
public:
void func(const MyClass &x)
{value = x.value;}
};
// 用一样的类型T才能够正确调用func
template
class MyClass
{
private:
T value;
public:
template
void func(const MyClass &x)
{value = x.Getvalue();}
T Getvalue() const
{return value;}
};
// 可以用不同的类型调用func
异常处理:
class Error;
void func()
{
//.......
if(exception-condition)
{
throw Error(); //抛出一个异常
}
}
try{
func();
}
catch (const Error&){ //捕获异常
//处理异常
}
namespace 的用法
namespace Mathison
{
class MyClass;
void func();
}
Mathison::MyClass P;
Mathison::func();
//OR
using Mathison::MyClass; //是一个using declaration
using namespace Mathison; //是一个using directive,使得该空间内的名字全部曝光
explicit 的用法
禁止单参数构造函数自动进行类型转换
也可以阻止具有转型操作的初始化
class MyClass
{
private:
int value;
public:
MyClass(){value = 0;}
MyClass(int x){value = x;} //#1
//explicit MyClass(int x){value = x;} //#2
int getValue(){return value;}
};
int main()
{
MyClass P;
P = 40; //#1 没有问题,value被赋值为40
//P = 40; //#2 编译出错
cout<
类型转换
//static_cast 符合逻辑的转换
double x;
static_cast(x); //double--->int
static_cast("string"); char *--->string
//dynamic_cast 将多态类型向下转换为实际静态类型
class Car;
class Cabriolet: public Car{};
Car *cp;
Cabriolet * cab = dynamic_cast (cp);
//const_cast 去除常数性 也可去除volatile
//reinterpret_cast 重新解释bits意义 不利于移植
常数静态成员
class MyClass{
static const int num = 10;
int Elem[num];
};
const int MyClass::num; //不初始化
main
int main(){}
int main(int argc, char **argv){} //or char *argv[]
pair 的用法
//pair 定义于 是一种structure
std::pair p;
//p.first p.second
//以下二者等价
std::make_pair(4,'@');
std::pair(4, '@');
std::pair(4, 7.7); //int, float
std::make_pair(4, 7.7); //int, double
//输出pair
template
std::ostream& operator << (std::ostream& strm, std::pair& p)
{
return strm << "[" <
#include
int i = 0;
auto p = std::make_pair(std::ref(i), std::ref(i));
++p.first;
++p.second;
// i == 2
auto_ptr 智能指针 (旧标准C++98)
帮助程序员防止被异常抛出时发生资源泄露
void func()
{
MyClass *ptr = new MyClass();
//........
delete ptr;
}
//solution one
void func()
{
MyClass *ptr = new MyClass();
//........
try{
}
catch(){
delete ptr; //每个catch都要delete
throw;
}
delete ptr;
}
//solution two
std::auto_ptr ptr(new MyClass); //不需要delete 以及catch
std::auto_ptr ptr = new MyClass; //ERROR
//指针算术(ptr++)都没有定义
tuple 的用法
#include
tuple t1(10,20,"aaa");
auto t2 = std::make_tuple(20,30,"bbb");
get<1>(t1) = get<1>(t2);
string s;
tuple t(s); //引用
//tuple必须指明访问元素的下标
int i = 0;
get(t); //编译时会出错
//引用的赋值
std::tuple s(10, 20, "aaa");
int i;
float f;
string str;
std::make_tuple(std::ref(i),std::ref(f),std::ref(str)) = s; //利用tuple给i,f,str赋值
//OR
std::tie(i, f, str) = s;
//tuple的构造函数用了explicit修饰
void foo(const std::tuple t;
foo(42); //ERROR
foo(make_tuple(42)); //OK
//初始化
std::tuple t1(10, 7.0); //OK
std::tuple t2{10, 7.0}; //OK
std::tuple t3 = {10, 7.0}; //ERROR
//{}list赋值
std::vector> t = {{1,2,3}, {2,3,4}}; //OK
std::vector> t = {{1,2,3}, {1,2,3}}; //ERROR
std::vector> t = {std::make_tuple(1,2,3), std::make_tuple(2,3,4)}; //OK
//value type
typedef std::tuple TupleType;
std::tuple_size::value; //==3
std::tuple_element<1, TupleType>::type; //==float
//tuple_cat
int n = 0;
auto p = std::tuple_cat(std::make_tuple(10, 7.0, "aaa"), std::tie(n));
//printtuple
#include ""printtuple.hpp"
std::tuple t(10, 2.4);
cout<<"io:"<
智能指针 (C++11)
分为两类:shared_ptr 、unique_ptr
均包含在 memory 中
//shared_ptr 共享权限,在对象不再使用时清空
//允许多个指针共享对象,最后一个负责释放资源
#include
shared_ptr aaa(new string("aaa")); //用explicit修饰,不能直接赋值(用到了隐含类型转换)
shared_ptr bbb(new string("bbb")); //or: shared bbb = make_shared("bbb");
std::vector> whoMakeCoffee;
whoMakeCoffee.push_back(aaa);
whoMakeCoffee.push_back(bbb);
whoMakeCoffee.push_back(aaa);
whoMakeCoffee.push_back(bbb);
whoMakeCoffee[0].use_count(); //2 共享对象的指针数量
for(auto ptr : whoMakeCoffee)
{
cout<< *ptr << " " << endl;
}
//shared_ptr 的赋值
shared ptr;
ptr = new string("aaa"); //ERROR
ptr.reset(new string("aaa")); //OK
//智能指针的delete
//shared_ptr 只提供delete 而不提供delete []
std::shared_ptr ptr(new int[10]); //ERROR
std::shared_ptr ptr(new int[10], [](int* p){delete []p;}); //OK
std::shared_ptr ptr(new int[10], std::default_delete()); //OK
//智能指针 文件操作
class FileDeleter
{
private:
string filename;
public:
FileDeleter(const string& fn) :filename(fn){}
void operator () (ofstream* fp){ //include
fp->close();
std::remove(filename.s_str()); //include
}
};
int main()
{
shared_ptr fp(new std::ofstream("tmpfile.txt"),FileDeleter("tmpfile.txt"));
}
//weak_ptr的作用
//shared_ptr在循环引用和只共享中会出现问题
//weak_ptr只共享不拥有
//weak_ptr不能使用 *ptr ptr->等
shared_ptr peter;
vector> kids; //会导致循环引用,count不为1,无法释放
vector> kids; //解决了问题
peter->mom->kids[0]->name; //无法通过weak_ptr访问
peter->mom->kids[0].lock()->name; //将weak_ptr转换为shared_ptr
//检验一个weak_ptr是否存在
//1、expired()
//2、使用shared_ptr构造函数进行转换,若不存在则报错
//3、use_count()
try{
shared_ptr sp(new string("aaabbb"));
weak_ptr wp = sp;
sp.reset(); //释放对象
wp.expired(); //true
wp.use_count(); //0
shared_ptr p(wp);
}
catch(const std::exception& e){
cerr << e.what() < sp1(N);
shared_ptr sp2(N); //ERROR
shared_ptr sp1(new int);
shared_ptr sp2(sp1); //OK
void Person::setParentsKids(shared_ptr m=nullptr, shared_ptr d=nullptr)
{
mom = m;
dad = d;
if(!m==nullptr)
{
m->kids.push_back(shared_ptr(this)); //ERROR 这样压入容器中的指针与this不是同一组
}
//....
}
//solution
class Person : public std::enable_shared_from_this(Person){};
m-kids.push_back(shared_from_this()); //OK !!但是其不能用在Person构造函数中
//智能指针当其为所指对象最后一个指针时
//指向另一个对象、使用reset()均会自动调用delete