value classes
- appear to be primitive data types
- passed to and returned from functions
- have overloaded operators(often)
- can be converted to and from other types
- example: Complex, Data, String
user-defined type conversions
- a conversion operator can be used to convert an object of one class into:
- an object of another class
- a built-in type
- compilers perform implicit conversions using:
- single-argument constructor
- implicit type conversion operators
single argument constructors
class PathName{
string name;
Public:
//or could be muli-argument with defaults
PathName(const string&);
~PathName();
};
...
string abc("abc");
PathName xyz(abc);//ok
xyz = abc; //ok abc => PathName
class One{ public: One(){} }; class Two{ public: Two(const One&){} }; void f(Two){} int main(){ One one; f(one); //wants Two.has a One }
preventing implicit conversions
-
new keyword:explicit
class PathName{ string name; public: explicit PathName(const stirng&); // 显式 ~PathName(); }; ... string abc("abc"); PathName xyz(abc);//ok! xyz = abc;//error
class One{ public: One(){} }; class Two{ public: explicit Two(const One&){} }; void f(Two){} int main(){ One one; // f(one);//no auto conversion allowed f(Two(one));//ok--user performes conversion }
conversion operations
- operator conversion
- function will be called automatically
- return type is same as function name
class Rational{ public: ... operator double() const;//Rational to double this 变成 double } Rational::operator double() const{ // 没有返回类型 return numerator_/(double)denominator_; } Rational r(1,3); double d = 1.3*r;//r=> double
general form of conversion ops
- X::operator T()
- operator name is any type descriptor
- no explicit arguments
- no return type
- complier will use it as type conversion from X=>T
c++ type conversions
-
built-in conversions
- Primitivec
- char => short => int => float => double int => long
- Implicit (for any type T)
- T => T&(赋值) T& => T(初始化或赋值)
- T* => void* T[] => T* T* => T[] T => const T
- Primitivec
-
user-defined T => C
- if "C(T)" is a valid constructor call for c c类有个构造函数
- if operatorC() is defined for T T类有operatorC()
-
BUT
class Orange;//class declaration 前向声明 class Apple{ Public: operator Orange() const;//Convert Apple to Orange }; class Orange{ public:
Orange(Apple);//Convert Apple to Orangeexplicit Orange(Apple);// 可以,但是尽量别用 }; void f(Orange){} int main(){ Apple a; // f(a);//error:ambigunous conversion 编译器不知道用哪个 }
do you want to use them?
-
in genaral, no!
- cause lots of problems when functions are called unexpectedly
-
use explicit conversion functions.for example,in class Rational instead of the conversion operator ,declare a member function:
double toDouble() const; // 更容易理解