标签:strong isnull 调用 iostream 隐式类型转换 出现 des 避免 隐式
内存泄漏(臭名昭著的Bug):
我们需要什么:
解决方案:
示例——实现智能指针:
#include <iostream>
#include <string>
using namespace std;
class Test
{
int i;
public:
Test(int i)
{
cout << "Test(int i)" << endl;
this->i = i;
}
int value()
{
return i;
}
~Test()
{
cout << "~Test()" << endl;
}
};
class Pointer
{
Test* mp;
public:
Pointer(Test* p = NULL)
{
mp = p;
}
Pointer(const Pointer& obj)
{
mp = obj.mp;
const_cast<Pointer&>(obj).mp = NULL;
}
Pointer& operator = (const Pointer& obj)
{
if( this != &obj )
{
delete mp;
mp = obj.mp;
const_cast<Pointer&>(obj).mp = NULL;
}
return *this;
}
Test* operator -> ()
{
return mp;
}
Test& operator * ()
{
return *mp;
}
bool isNull()
{
return (mp == NULL);
}
~Pointer()
{
delete mp;
}
};
int main()
{
Pointer p1 = new Test(3);
cout << p1->value() << endl;
Pointer p2 = p1;
cout << p1.isNull() << endl;
cout << p2->value() << endl;
return 0;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test(int i)
3
1
3
~Test()
智能指针的使用军规——只能用来指向堆空间中的对象或者变量
再论类型转换:
C语言标准数据类型之间会进行隐式的类型安全转换
C语言转换规则如下:
(C语言编译器支持从小类型(占用内存少)转换到大类型(占用内存多)的隐式类型转换,因为这样的转换是安全的,不会发生数据截断或者数据丢失。)
示例——隐式类型转换的bug:
#include <iostream>
#include <string>
using namespace std;
int main()
{
short s = ‘a‘;
unsigned int ui = 1000;
int i = -2000;
double d = i;
cout << "d = " << d << endl;
cout << "ui = " << ui << endl;
cout << "ui + i = " << ui + i << endl;
if( (ui + i) > 0 )
{
cout << "Positive" << endl;
}
else
{
cout << "Negative" << endl;
}
cout << "sizeof(s + ‘b‘) = " << sizeof(s + ‘b‘) << endl;
return 0;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
d = -2000
ui = 1000
ui + i = 4294966296
Positive
sizeof(s + ‘b‘) = 4
(在大多数编译器看来,int类型,也就是4个字节的整型数的运算是最高效的。而在sizeof(s + ‘b‘)中,是做加法运算,左操作数和右操作数都可以安全的转换为int,那么可以采用更高效的方式来进行运算。于是就出现bug了!)
问题:
普通类型与类类型之间能否进行类型转换?
类类型之间能否进行类型转换?
再论构造函数:
旧式的C方式强制类型转换:
编译器会尽力尝试让源码通过编译(普通类型->类类型):
示例——编译器自作聪明的行为:
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test() { mValue = 0; }
Test(int i) { mValue = i; }
Test operator + (const Test& p)
{
Test ret(mValue + p.mValue);
return ret;
}
int value() { return mValue; }
};
int main()
{
Test t;
t = 5; // t = Test(5);
Test r;
r = t + 10; // r = t + Test(10);
cout << r.value() << endl;
return 0;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
15
编译器尽力尝试的结果是隐式类型转换。
隐式类型转换:
工程中通过explicit关键字杜绝编译器的转换尝试
转换构造函数被explicit修饰时只能进行显示转换
转换方式:
示例——杜绝编译器的转换尝试:
#include <iostream>
#include <string>
using namespace std;
class Test
{
int mValue;
public:
Test() { mValue = 0; }
explicit Test(int i) { mValue = i; }
Test operator + (const Test& p)
{
Test ret(mValue + p.mValue);
return ret;
}
int value() { return mValue; }
};
int main()
{
Test t;
t = static_cast<Test>(5); // t = Test(5);
Test r;
r = t + static_cast<Test>(10); // r = t + Test(10);
cout << r.value() << endl;
return 0;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
15
问题:
类类型是否能够类型转换到普通类型?
类型转换函数:
示例——只有想不到,没有做不到:
#include <iostream>
using namespace std;
class Test
{
int mValue;
public:
Test(int i = 0) { mValue = i; }
operator int() { return mValue; }
};
int main()
{
Test t(100);
int i = t; // ==> t.operator int()
cout << "i = " << i << endl;
return 0;
}
运行结果为:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
i = 100
类型转换函数:
编译器会尽力尝试让源码通过编译:
类型转换函数 vs 转换构造函数:
示例——能通过编译的类型转换函数:
#include <iostream>
#include <string>
using namespace std;
class Test;
class Value
{
public:
Value() {}
};
class Test
{
int mValue;
public:
Test(int i = 0) { mValue = i; }
int value() { return mValue; }
operator Value()
{
Value ret;
cout << "operator Value()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Value v = t; // ==> t.operator Value()
return 0;
}
示例——能通过编译的转换构造函数:
#include <iostream>
#include <string>
using namespace std;
class Test;
class Value
{
public:
Value() {}
Value(Test& t) {}
};
class Test
{
int mValue;
public:
Test(int i = 0) { mValue = i; }
int value() { return mValue; }
};
int main()
{
Test t(100);
Value v = t; // ==> Value(t)
return 0;
}
示例——冲突的类型转换函数与转换构造函数:
#include <iostream>
#include <string>
using namespace std;
class Test;
class Value
{
public:
Value() {}
Value(Test& t) {}
};
class Test
{
int mValue;
public:
Test(int i = 0) { mValue = i; }
int value() { return mValue; }
operator Value()
{
Value ret;
cout << "operator Value()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Value v = t;
return 0;
}
报错信息为:
[root@bogon Desktop]# g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:32: error: conversion from ‘Test’ to ‘Value’ is ambiguous
test.cpp:21: note: candidates are: Test::operator Value()
test.cpp:12: note: Value::Value(Test&)
示例——使用explicit关键字避免冲突:
#include <iostream>
#include <string>
using namespace std;
class Test;
class Value
{
public:
Value() {}
explicit Value(Test& t) {}
};
class Test
{
int mValue;
public:
Test(int i = 0) { mValue = i; }
int value() { return mValue; }
operator Value()
{
Value ret;
cout << "operator Value()" << endl;
return ret;
}
};
int main()
{
Test t(100);
Value v = t;
return 0;
}
标签:strong isnull 调用 iostream 隐式类型转换 出现 des 避免 隐式
原文地址:https://www.cnblogs.com/PyLearn/p/10086952.html