oprator type() const; explicit complex(...): initialization list { } pointer-like object function-like object Namespace template specialization Standard Library |
since C++11: variadic template move ctor Rvalue reference auto lambda range-base for loop unordered containers ...... |
conversion function, 转换函数 ---------1⃣️
operator 类型 () const {...}
//e.g fraction类--一个double型小数
class Fraction{
public:
//功能:将其他类型转换成该类型
Fraction(int num, int den = 1): m_numerator(num), m_denominator(den) { }
//conversion function, 转换函数
//功能:让该类可以作为小数使用,没有return type,没有参数传入,const修饰函数
operator double() const {
return (double) (m_numerator / m_denominator);
}
private:
int m_numerator;//分子
int m_denominator;//分母
}
//test
Fraction f(3, 5);
double d = 4 + f; //调用operator double()将f转换为0.6
non-explict-one-argument constructor,不清晰的单参数构造函数 ----------2⃣️
class Fraction{
public:
//non-explict-one-argument constructor,不清晰的单参数构造函数
//功能:将其他类型转换成该类型
Fraction(int num, int den = 1): m_numerator(num), m_denominator(den) { }
//函数重载“+”:左值为本身,右值为传入参数
Fraction operator+(const Fraction& f){
return Fraction(...);
}
private:
int m_numerator;
int m_denominator;
};
//test
Fraction f(3,5);
Fraction d2 = f + 4; //调用non-explict-one-argument ctor
//再调用operator+
若1⃣️和2⃣️并存,可能会有二义性/多条路径(函数)实现 -- error
explict-one-argument constructor,明确的单参数构造函数
class Fraction{
public:
//explict-one-argument constructor,明确的单参数构造函数
explicit Fraction(int num, int den = 1): m_numerator(num), m_denominator(den) { }
operator double() const {
return (double) (m_numerator / m_denominator);
}
Fraction operator+(const Fraction& f){
return Fraction(...);
}
private:
int m_numerator;
int m_denominator;
};
//test
Fraction f(3,5);
Fraction d2 = f + 4; //Error:conversion from 'double' to 'Fraction' requested
pointer-like classes,关于智能指针
template<class T>
class share_ptr{
public:
T& operator*() const{
return *px;
}
T* operator->() const{
return px;
}
share_ptr(T* p) : px(p) { }
private:
T* px;
long* pn;
...
};
“->”重载后还是会继续使用
pointer-like classes, 关于迭代器
reference oprator*() const{
return (*node).data;
}
pointer operator->() const{
return &(operator*());
}
//***************************⬇️
list<Foo>::iterator ite;
...
*ite; //获得一个 Foo object
ite->method();
//意思是调用 Foo::method()
//相当于(*ite).method();
//相当于(&(*ite))->method();
namespace
using namespace std;
//----------------------
namespace jj01{
...
}
namespace jj02{
...
}
//test
int main(int argc, char** argv){
jj01::test_member_template();
jj02::test_member_template_param();
}
class template, 类模版
function template, 函数模版
调用会进行实参推导,能推出类型,所以在调用时不需要制定类型
member template, 成员模版
template <class T1, class T2>//template class
struct pair{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair()
:first(T1()), second(T2()) { }
pair(const T1& a, const T2& b)
:first(a), sencond(b) { }
template <class U1, class U2>//template member
pair(const pair<U1, U2>& p):
first(p.first), second(p.sencond) { }
//很多成员模版会出现在类模版的构造函数中
};
specialization, 模版特化
泛化 <---betray---> 特化
full specialization & partial specialization
//泛化
template <class key>
struct hash { };
//特化
template<>
struct hash<char> {
size_t operator()(char x)const { return x; }
};
template<>
struct hash<int> {
size_t operator()(int x)const { return x; }
};
template<>
struct hash<long> {
size_t operator()(long x)const { return x; }
};
partial specialization, 模版偏特化 -- 个数上的偏
partial specialization, 模版偏特化 -- 范围上的偏
template template parameter, 模版模版参数
//template template parameter -- Container
template<typename T,
template <typename T>
class Container//容器
>
class XCls{
private:
Container<T> c;
public:
...
};
template<typename T>
using Lst = list<T, allocator<T>>;
//test
XCls<string, list> mylst1; //error:list容器有第二、第三默认值?
XCls<string, Lst> mylst2; //right
//template template parameter -- smartPtr
template<typename T,
template <typename T>
class SmartPtr//智能指针
>
class XCls{
private:
SmartPtr<T> sp;
public:
XCls() : sp(new T) { }
};
//test
XCls<string, share_ptr> p1; //right
XCls<double, unique_ptr> p2; //error
XCls<int, weak_ptr> p3; //error
XCls<long, auto_ptr> p4; //right
C++标准库
仿函数Functors;算法Algorithm;迭代器Iterators;容器Containers
1.variadic templates -- 数量不定的模版参数
void print(){
}
template <typename T, typename... Types>
void print(const T& firstArg, const Types&... args){
cout << firstArg << endl;
print(args...);//递归:拆成一个和一包
}
//test
print(7.5, "hello", bitset<16>(377), 42);//最后42时传入的是一个和0个
//调用42结束之后就会调用第一个空函数printf()
...就是一个所谓的pack(包)
用于template parameters,就是 template parameters park(模版参数包);
用于function parameter types,就是 function parameter types park(函数参数类型包);
用于function parameters,就是 function parameters park(函数参数包)
2.auto(C++11)
auto被定义为自动推断变量的类型
list<string> c;
...
list<string>::iterator ite;//ite的title-->可以用auto代替
ite = find(c.begin(), c.end(), target);
***
list<string> c;//创建一个容器
...
auto ite = find(c.begin(), c.end(), target);
***
//error: auto时要初始化
list<string> c;
...
auto ite;//error
ite = find(c.begin(), c.end(), target);
3.ranged-base for (since C++11)
//decl--定义/声明一个变量; Coll--容器
for( decl : coll ) {
statement
}
//example:
// {2, 3, 5, 7, 9, 13, 17, 19} -- 自然而然声明的容器
for(int i : {2, 3, 5, 7, 9, 13, 17, 19} ) {
cout << i << endl;
}
vector<double> vec;
...
//auto 可以去 “猜” elem的类型
//pass by value
for( auto elem : vec ) {
cout << elem << endl;
}
//pass by reference
for( auto& elem : vec ) {
elem *= 3; //改变值需要用reference
}
reference
sizeof(reference) = sizeof(x) -- object和其reference的大小相同,地址也相同
reference的常见用途
reference通常不用于声明变量,而用于参数类型parameters type和返回类型return type的描述
//以下被视为same signature
//二者不能同时存在
double imag(const double& im) {...}
double imag(const double im) {...}//ambiguity
const是函数的一部分,若两个相同函数一个有const一个没有 是可以共存的
关于vptr虚指针 和 vtbl虚表
类内有虚函数时,有指针(4个字节)
通过指针调用虚函数时,是动态绑定dynamic binding -- 虚机制
动态绑定 : 1.通过指针;2.指针向上转型动作;3.调用的是虚函数
关于new, delete
array new 一定要搭配 array delete
重载 内存池设计
::operator new, ::operator delete, ::operator new[], ::operator delete[]
void* myAlloc(size_t size){
return malloc(size);
}
void myFree(void* ptr){
return free(ptr);
}
//它们不可以被声明在一个namespace内
inline void* operator new(size_t size){
cout << "jjhou global new() \n";
return myAlloc(size);
}
inline void* operator new[](size_t size){
cout << "jjhou global new[]() \n";
return myAlloc(size);
}
inline void* operator delete(void* ptr){
cout << "jjhou global delete() \n";
myFree(ptr);
}
inline void* operator delete[](void* ptr){
cout << "jjhou global delete[]() \n";
myFree(ptr);
}
const