C++学习笔记
2013-10-20 01:07
302 查看
C++学习笔记
1、explicit关键字的用法:
C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?
如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:
class MyClass
{
public:
MyClass( int num );
}
//.
MyClass obj = 10; //ok,convert int to MyClass
在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:
MyClass temp(10);
MyClass obj = temp;
上面的所有的C++ explicit关键字相关的操作即是所谓的"隐式转换"。
如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:
class MyClass
{
public:
explicit MyClass( int num );
}
//.
MyClass obj = 10; //err,can't non-explict convert
总结:通过使用explicit关键字来标记构造函数,可以禁止这个类的隐式转换,而且explicit关键字只能放在类定义中,而且只适用于仅有一个参数的构造函数。
2、mutable关键字的用法:
mutalbe的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。
在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。
我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,有些时候,我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该被mutalbe来修饰。
下面是一个小例子:
类ClxTest的成员函数Output是用来输出的,不会修改类的状态,所以被声明为const的。
函数OutputTest也是用来输出的,里面调用了对象lx的Output输出方法,为了防止在函数中调用其他成员函数修改任何成员变量,所以参数也被const修饰。
如果现在,我们要增添一个功能:计算每个对象的输出次数。如果用来计数的变量是普通的变量的话,那么在const成员函数Output里面是不能修改该变量的值的;而该变量跟对象的状态无关,所以应该为了修改该变量而去掉Output的const属性。这个时候,就该我们的mutable出场了——只要用mutalbe来修饰这个变量,所有问题就迎刃而解了。
下面是修改过的代码:
计数器m_iTimes被mutable修饰,那么它就可以突破const的限制,在被const修饰的函数里面也能被修改。
3、超类方法有默认参数:
子类和超类都可以有不同的默认参数,但是使用的参数依赖于变量的声明类型,而不是底层的对象,例子如下:
输出结果为:
原因分析:C++把默认参数与指示对象的变量类型绑定在一起,而不是与对象本身绑定,也是由于这个原因,在C++中,不能继承默认参数,如果一定要有默认的话,父类和子类的默认参数必须是一样的,这样才不会出现问题
1、explicit关键字的用法:
C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?
如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:
class MyClass
{
public:
MyClass( int num );
}
//.
MyClass obj = 10; //ok,convert int to MyClass
在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:
MyClass temp(10);
MyClass obj = temp;
上面的所有的C++ explicit关键字相关的操作即是所谓的"隐式转换"。
如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显式",也就是在声明构造函数的时候前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显式的,那么下面的代码就不能够编译通过了,如下所示:
class MyClass
{
public:
explicit MyClass( int num );
}
//.
MyClass obj = 10; //err,can't non-explict convert
总结:通过使用explicit关键字来标记构造函数,可以禁止这个类的隐式转换,而且explicit关键字只能放在类定义中,而且只适用于仅有一个参数的构造函数。
2、mutable关键字的用法:
mutalbe的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。
在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。
我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,有些时候,我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该被mutalbe来修饰。
下面是一个小例子:
class ClxTest { public: void Output() const; }; void ClxTest::Output() const { cout << "Output for test!" << endl; } void OutputTest(const ClxTest& lx) { lx.Output(); } |
函数OutputTest也是用来输出的,里面调用了对象lx的Output输出方法,为了防止在函数中调用其他成员函数修改任何成员变量,所以参数也被const修饰。
如果现在,我们要增添一个功能:计算每个对象的输出次数。如果用来计数的变量是普通的变量的话,那么在const成员函数Output里面是不能修改该变量的值的;而该变量跟对象的状态无关,所以应该为了修改该变量而去掉Output的const属性。这个时候,就该我们的mutable出场了——只要用mutalbe来修饰这个变量,所有问题就迎刃而解了。
下面是修改过的代码:
class ClxTest { public: ClxTest(); ~ClxTest(); void Output() const; int GetOutputTimes() const; private: mutable int m_iTimes; }; ClxTest::ClxTest() { m_iTimes = 0; } ClxTest::~ClxTest() {} void ClxTest::Output() const { cout << "Output for test!" << endl; m_iTimes++; } int ClxTest::GetOutputTimes() const { return m_iTimes; } void OutputTest(const ClxTest& lx) { cout << lx.GetOutputTimes() << endl; lx.Output(); cout << lx.GetOutputTimes() << endl; } |
3、超类方法有默认参数:
子类和超类都可以有不同的默认参数,但是使用的参数依赖于变量的声明类型,而不是底层的对象,例子如下:
class A { public: virtual void go(int i = 2){ cout << "A's go with param " << i << endl;} }; class B : public A { public: virtual void go(int i = 7){ cout << "B's go with param " << i << endl;} }; int main() { A a; B b; A *p = &b; a.go(); b.go(); p->go(); }
输出结果为:
原因分析:C++把默认参数与指示对象的变量类型绑定在一起,而不是与对象本身绑定,也是由于这个原因,在C++中,不能继承默认参数,如果一定要有默认的话,父类和子类的默认参数必须是一样的,这样才不会出现问题
相关文章推荐
- C\C++ 程序员从零开始学习Android - 个人学习笔记(四) - java基础 - 数据类型、变量、字符串、数组
- C++学习笔记--函数指针
- static关键字用法学习笔记(C++)
- C++基础学习笔记----第十四课(new和malloc的区别、单例模式等深入)
- The C++ Programming Language 学习笔记 第6章 表达式和语句
- C++学习笔记
- c++学习笔记
- 设计模式C++学习笔记之三(Singleton单例模式)
- C++学习笔记,字符串输入
- C/C++学习笔记5-栈的工作流程
- C++基础的不能再基础的学习笔记——拷贝控制(一)
- C++中内联函数的使用学习笔记
- 设计模式C++学习笔记之十九(State状态模式)
- 慕课学习C++笔记02-封装(下)
- 《C++ Primer Plus》第3章 处理数据 学习笔记
- 【C++ 学习笔记】 MFC CEdit
- C++学习笔记 - 面向对象编程
- 【C学习笔记】【疑问】关于const常量的实现机制在C和C++中的不同
- C++学习笔记(5)
- 设计模式C++学习笔记之二(Bridge桥梁模式)