C++常见错误 - 总结2

1,拷贝构造函数和赋值运算符重载函数各在什么情况下调用:

#include<iostream>
using namespace std;
class MyClass
{
public:
    MyClass(int i = 0)
    {
        cout << i;
    }
    MyClass(const MyClass &x)
    {
        cout << 2;
    }
    MyClass &operator=(const MyClass &x)
    {
        cout << 3;
        return *this;
    }
    ~MyClass()
    {
        cout << 4;
    }
};
int main()
{
    MyClass obj1(1), obj2(2);
    MyClass obj3 = obj1;
    return 0;
}

在这里,obj3还不存在,所有调用拷贝构造函数,也就数输出5
如果obj3存在,在调用复制运算符重载函数。输出3

2,Release版和Debug版的区别?

1,在debug模式下,编辑器会记录很多调试信息,也可以加入很多测试代码,比如断言assert,方便程序员测试,以及出现bug时分析解决
2,Release模式下,就没有上述的那些调试信息,而且编辑器也会自动优化一些代码,这样生成的程序时最优的,但是如果出现问题,不便于就行调试分析。

注:assert断言,它是标准C++的assert头文件的一个宏,用来判断一个条件表达式的值是否为true,如果不为true,则程序会终止,并且报告错误,这样就容易定位错误。

3,void的大小,void *的大小

sizeof(void)。可能会编译错误,或者为1
sizeof(void*),即空指针,根据系统不同32位系统时:其大小为4;64位系统时,大小为8

4 ,C++中的强制类型转换,各种cast.

C++中显示类型转换也称为强制类型转换,包括下列名字命名的强制类型转换操作符:
static_cast,dynamic_cast,const_cast和reinterpret_cast。

  • reinterpret_cast
    在引入命名的的强制类型转换操作符之前,显示强制类型转换用圆括号将类型括起来来实现。
int *ip;
char *pc = (char *) ip;

效果与使用reinterpret_cast符号相同

int *ip;
char *pc = reinterpret<char*> (ip);
  • const_cast
    转换掉表达式const性质,例如
const char *pc_str;
char *pc = const_cast<char*>(pc_str);

只用使用const_cast才能将const性质转换掉。也就是说用其他三种方式强制转换都会导致编译时的错误。
同时,除了添加和删除const操作,用const_cast符来执行其他任何类型的转换,都会引起编译错误。

  • static_cast
    编译器隐式执行的任何类型转换都可以用static显示的完成。
    仅当类型之间可隐式转换时(除类层次减的下行转换意外),static_cast转换才是合法的。否则将出错。

a,基础类型隐式转换

double d = 97.0
int i = static_cast<int>(d);

以上等价于

double d = 97.0;
int i = d;

注:C++基本数据类型指针之间不含有隐式转换(void*除外,const的某些用法为了兼容C语言也可以隐式转换)。
b,类类型隐式的转换

class base{};
class child:public base{};
base *b;
child *c;
c = static_cast<child*>(b); //下行转换,正确
c = b;  //编译不正确

使用static_cast完成下行转换(把基类指针或引用转换成子类的指针或引用),由于没有动态类型检测,所以是不安全的。
注:c = b;编译器提示:invalid conversion from “base*” to “child”

  • dynamic_cast

该运算符价把expression转换成type类型的对象,type必须是类的指针,类的引用,或者void*。如果type是指针类型,则expression也必须是一个指针,如果type是一个引用,那么expression也必须是一样引用。也就是说,expression要和type类型一直。

与其他三者不同之处在于,dynamic_cast涉及运行时类型检查(RTTI)。

dynamic_cast运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类就没有虚函数表。对没有虚函数的表的类使用会导致dynamic_cast编译错误。

如果绑定到引用类型或指针的对象的类型不是目标类型,则dynamic_cast失败。如果转换到指针类型的dynamic_cast失败,则dynamic_cast的结果是0;如果转换到引用类型的dynamic_cast失败,则抛出bad_cast类型的异常。

例题:

已知下面的class层次,其中每一个class都定义有一个default constructor和一个virtual destructor;

class X{...};
class A{...};
class B:public A{...};
class C:public B{...};
class D:public X,public C{...};

下面()执行dynamic_cast会失败
这里写图片描述

分析:
A,pa实际指向D,然后使用dynamic_cast将其转换为X*类型,这就是向上转型,所以没有问题。
B,pd指向D,将pd转换为A*类型,这里也是向上转型,所以没有问题
C,pb指向B,将pb转换为D*类型,即pb绑定的对象类型并不是目标类型D*。所以失败
D,pa指向C,将pa转换为C*,因为pa绑定类型与目标类型相同,则没有问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值