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 defaultsPathName(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 allowedf(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
-
-
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; // 更容易理解