cpp软件架构狮 2018-07-22 18:24:46
1)模板关键字: template
2)定义的模板关键字当前行下一个函数或类有用。
3)分为函数模板和类模板;
4)一旦声明了多个类型 T ,不管用或不用,都必须给它指定类型。
1)函数模板具有自动推导功能
2)编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译。
3)函数模板通过具体的类型产生不同的函数。
1)函数模板不允许自动类型转换,必须严格匹配。
2)普通函数能自动进行类型转换
templateT ptint(T a, T b ){ } int show(int a,int b){ } void main(){ int a = 6; char b = 'c'; print(a,b); //"error",两个变量类型必须相同,不允许进行自动转换 show(a, b); //"YES" “普通函数能自动进行类型转换” }
1)函数模板可以像普通函数一样被重载
2)如果函数模板与普通函数一样,C++编译器优先调用普通函数。
例如: template
void print(T a, T b ){ }
void print(int a, int b){ }
void main(){ int a = 4; int b = 9; print(a, b); "此时优先调用普通函数"}
3)如果函数模板能产生更好的匹配,则优先调用函数模板。
例如:template
void print(T a, T2 b ){ }
void print(int a, int b){ }
void main(){ int a = 4; char b = 'u'; print(a, b); "此时优先调用函数模板"}
4)可以通过空模板实参列表的语法限定编译器只能调用模板函数
例如:(此目录第二个函数例子)
void main(){ int a = 4; int b = 6; print<>(a, b); }
1)只能显示的指定类型,不具有自动推导功能。
2)类模板做函数形参(必须显示指定模板类型)
templateclass Person { public: Person( T1 name, T2 age ) { this->mName = name; this->mAge = age; } public: T1 mName; T2 mAge; }; /* 类模板做函数参数(指定类型) */ void Dobusiness( Person &p1 ) { cout << "name:" << p1.mName << " age:" << p1.mAge << endl; } /* 类模板与函数模板混合使用(使用函数模板的自动推导功能) */ template void Dobusiness02( Person &p1 ) { cout << "name:" << p1.mName << " age:" << p1.mAge << endl; } void test04() { Person p1( "jonh", 30 ); Dobusiness( p1 ); Person p2( "jonheqeq", 303 ); Dobusiness02( p2 ); }
1)继承的话,应该继承一个具体的类,因为一个具体的类,编译器才知道分配多大的内存。
2)如果想继承类模板,应该给继承过程中的类模板显示指定类型。
例如(类模板派生普通类)
templateclass MyClass { private: //"父类模板" T age; }; class SubClass : public Mycalss { //"普通类,这里继承时,必须对类模板显示指定类型,编译器才知道给父类分配多大的内存" public: int a; }; /* 例如(类模板派生子类模板) */ template class MyClass { private: //"父类模板" T age; }; template class SubClass : public Mycalss { //"子类类模板,这里继承时,可以用子类的类型指定父类的模板" public: T a; };
C++文件的编译过程:先每个文件独立编译,然后由链接器将编译好的文件链接在一起(这一步就是寻找各种调用函数,和头文件的定义内容)
需要引入 .cpp 文件,原因:
1)C++编译机制的原因;(分文件编译导致的)
2)二次编译有关
解决办法文件,将他们放入:
类模板的声明与定义要放在一个文件中编写。创建一个.hpp将他们放入
"C++的类型转换"
1)用于类层次结构中基类和派生类之间"指针或引用"的转换
1)上行转换:把派生类的指针或引用转换成基类的是安全的 Animal *ani = static_cast
2)下行转换:把基类的指针或引用转换成派生类的是不安全的,因为没有动态类型检查。 Dog *dog = static_cast
3)总结一句就是:可以把大的转成小的; 不能把小的转成大的。
2)当两个类之间无继承关系时,不可以进行转换。
如:Teacher *t1 = static_cast
3)基础数据类型之间的转换:
1)可以把高精度的类型转换成低精度的;double da; int a = static_cast
2)当把低
精度的类型转换成高精度时,安全性需要程序员保证。(原理和上一样) double da = static_cast
dynamic_cast<> 具有类型检查功能,比 static_cast<>类型转换安全。
1)只能转换具有父子关系的"指针或引用".
上行转换:只能将子类指针转换成父类指针(可以大转小)
下行转换:不能将父类指针转换成子类指针(不能小转大);
例如: parent *parent = dynamic_cast
"1)自定义类型做元素构建数组时,必须提供无参构造函数。"
本页共117段,3029个字符,5662 Byte(字节)