c++ 新特性_1

typename
typename适用于在型别之前的标识符,如:

#include <iostream>  
#include <vector>  
using namespace std;  
class Num{
public:
	vector<int> num;
	Num(){num.push_back(1),num.push_back(2);}
	typedef int SubType;
};
template<class T>  
class Myclass{
private:
	int sum;
public:
	Myclass(int _sum = 0):sum(_sum){ }
	typename T::SubType	Sum( T coll){
		for(int i = 0;i <= 1;i++)
			sum += coll.num[i];
		return sum;
	}
};
int main()
{
	Num aa;
	Myclass<Num> a(0);
	cout << a.Sum(aa) << endl;
	return 0; 
}

如果不加typename会出现
在这里插入图片描述
此处的typename就是指出SubTypeclass T中的一个类型。
当然typename还可以用来代替关键字class

template <typename T> class Myclass;

Member Template成员模板,就是模板中再加入一个模板的声明余定义,如

#include<iostream>
using namespace std;

template <class T>
class Myclass {
private:
	T value;
public:
	Myclass(T _a) {
		value = _a;
	}
	template<class X>
	void assign(const Myclass<X>& x) {
		cout << x.getValue() << endl;
	}
	T getValue()const {
		return value;
	}
};
int main() {
	Myclass<double> d(1.2);
	Myclass<int> i(11);
	d.assign(d);
	d.assign(i);
	return 0;
}

其中的

	Myclass<double> d(1.2);
	Myclass<int> i(11);
	d.assign(d);
	d.assign(i);

di分别是double类型与int类型,然后再调用d.assign(d)时,传入的时令T = double,X = double,那么d.assign(d)就能够正常调用内嵌模板函数template<class X> void assign(const Myclass<X>& x){ };此外d.assign(i);T = double,X = init,也可正常调用函数。这就是内嵌模板的好处,两个类型之间可以自动转换,使用不同的内嵌模板函数。
但需要注意的是,当T != X时,即两个类型不一样时,我们在Myclass中的assign()的参数x*this的型别不一样,那么我们就不能够在assign()中直接存取Myclassprivate与protected成员,那么我们就只有另外加设一个函数,用于存取值,将上述代码实现中的

T getValue()const {
		return value;
	}

那么,其实这是因为assign()中的不同类型变量仍然可以访问Myclass中的public变量或者函数。


基本型别的显式初始化
如果采用不含参数,明确的构造函数调用语法,基本型别会被初始化为0,如:

#include<iostream>
using namespace std;
int main() {
	int i = 3;
	i = int();
	cout << i << endl;
	return 0;
}

执行结果
在这里插入图片描述
当然,这种功能更适用于模板函数中的初始化值,保证任何型别都有一个确切的初值,如
在这里插入图片描述


命名空间
namespace将不同的标识符集合在一个具名的作用域内。如果在namespace之内定义所有的标识符,那么namespace本声名称就成为唯一可能于其他全局符号冲突的标识符。那么在标识符前加namespace就可以应用namespace中的符号,之间用::隔开。

namespace std包含了其中的所有定义的标识符。

此外,using的使用也很常见:一个using声明一次只引入一个命名空间成员,如:

#include<iostream>
using std::cout;
int main()
{
    int x;
   // cin >> x;//wrong
    std::cin >> x;//right
    cout << x;//right
    return 0;
}

简写名字只能在声明它的作用域及其嵌套作用域中使用,一旦该作用域结束了,就必须使用完全限定名,如:

#include<iostream>
using namespace std;
namespace std{
    void print(int i) {
        cout << i << endl;
    }
}
void print(float f) {
    cout << f << endl;
}
int main()
{
    using std::print;//嵌套使用
    print(2.2);
    print(1);
    return 0;
}

在这里插入图片描述


explict
用于禁止单参数构造函数用于自动类型转换,如

class Myclass{
	explict Myclass(int num){ ... }

此时我们在如此调用就不行了,如
Myclass a = 12;因为我们使用explict禁止了自动转换调用构造函数。
注意区别一下两中操作

X x;
Y y(x);//显式调用
X x;
Y y = x;//隐式调用
发布了222 篇原创文章 · 获赞 48 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_44116998/article/details/104706341