const

const指针

 char greeting[] ="hello";
char* p = greeting; // non-const pointer, non-const data
const char* p = greeting; // non-const pointer, const data
char* const p = greeting; // const pointer, non-const data
const char* const p = greeting; //const pointer, const data
 void f1(const Object* o);
void f2(Object const* o);

这两个是一样的;

const vector<int>::iterator更像是T* const;

vector<int>::const_iterator更像是const T*;

enum不能取地址,const可以取地址,define没有任何约束;

const函数是为了可以操作const对象;

 class Test {
public:
void print() const {}
void mut() const { m1 = ; }
private:
mutable int m1; // can be changed even in const functions
};
const Test t;
t.print();
t. mut(); //legal

const版本和非const版本的代码重用。实现const函数,在non-const函数中调用const版本。

 class Test {
public:
const int& operator[](int i) const {...}
int& operator[](int i) {
const_cast<int&>(static_cast<const Test&>(*this)[i]);
}
};

singleton的初始化实现

local static 能够确保在调用时已经初始化。但是仍然不能确保线程安全。所有non-const的static对象,无论它是local还是non-local,在多线程环境下都会有问题。解决的方法就是在一开始的单线程环境下,手动调用这些函数实现初始化。这样可以避免与初始化有关的race conditions。

 class Test {
public:
Test& test() {
static Test t;
return t;
}
};

这种方式仅适用于创建对象;明确是惟一对象时才可使用。

virtual

多态的析构函数,设成virtual,这样在delete的时候才会释放子类的所有资源。

 class Parent {
public:
virtual ~Parent() {...}
};
class Child1: public Parent {};
Parent* p = new Child1;
delete p;

多态的析构函数必须是virtual。

在析构函数里,尽量不要调用会发生异常的操作。如果有,也要提供额外的接口,让用户有机会自己调用处理。

不要在构造函数或析构函数里调用virtual 函数。此时调用virtual函数,调用的是base类的版本。

对于自我实现的类,尽量以pass-by-reference-to-const替换pass-by-value;对于内置类型,以及stl的迭代器和函数对象,尽量以pass-by-value。

调用父类函数:

 class child1 : public Parent {
public:
virtual void print() {
Parent::print();
}
};

同名遮掩

 class Parent {
public:
void t1(int) {}
void t1() {}
};
class Child1 : public Parent {
public:
void t1() {}
};
class Child2 : public Parent {
public:
using Parent::t1;
void t1() {}
};
Child1 c1;
c1.t1(); // error
Child2 c2;
c2.t1(); // right

不使用using,父类的重载函数会被子类所遮掩,看不到了。

  • 如果派生类的函数与基类的函数同名,但是参数不同。此时,若基类无virtual关键字,基类的函数将被隐藏。(注意别与重载混淆,虽然函数名相同参数不同应称之为重载,但这里不能理解为重载,因为派生类和基类不在同一名字空间作用域内。这里理解为隐藏)
  • 如果派生类的函数与基类的函数同名,但是参数不同。此时,若基类有virtual关键字,基类的函数将被隐式继承到派生类的vtable中。此时派生类 vtable中的函数指向基类版本的函数地址。同时这个新的函数版本添加到派生类中,作为派生类的重载版本。但在基类指针实现多态调用函数方法时,这个新的派生类函数版本将会被隐藏。
  • 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏。(注意别与覆盖混淆,这里理解为隐藏)。
  • 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数有virtual关键字。此时,基类的函数不会被“隐藏”。(在这里,你要理解为覆盖哦^_^)

template

嵌套的类型名称,是需要在修饰符前加上typename的。

 template<typename C>
void print(const C& c) {
typename C::const_iterator iter(c.begin());
/* ... */
}

这里只能用typename,不能用class。

编译细节

 class A {
public:
void print() {cout << "a" << endl;}
}; int main(int argc, char** argv) {
A* pa = ;
pa->print(); return ;
}

这样的代码会core吗?不会,其实编译之后相当于print(A* this), 这时传入一个0,函数里面没有用,所以不会发生段错误。

类型转换

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

dynamic_cast运算符可以在执行期决定真正的类型。如果 downcast 是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果 downcast 不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。

dynamic_cast要求父类必须有虚函数。static_cast会在编译期就告诉你能不能转。

class D {
};
class E: public D {
};
int main(int argc, char** argv) {
D* d = new E();
E* e = static_cast<E*>(d);
E* f = dynamic_cast<E*>(d);
return ;
}

这里D没有一个虚函数,所以会输出:

 t.cpp: In function ‘int main(int, char**)’:
t.cpp::: error: cannot dynamic_cast ‘d’ (of type ‘class D*’) to type ‘class E*’ (source type is not polymorphic)
E* f = dynamic_cast<E*>(d);

如果:

 int main(int argc, char** argv) {
D* d = new D();
E* e = static_cast<E*>(d);
E* f = dynamic_cast<E*>(d);
cout << (f ? "addr" : "null") << endl;
return ;
}

从D转到E,这样dynamic_cast会返回null。

如果:

int main(int argc, char** argv) {
E* e = new E();
D* d = static_cast<D*>(e);
D* f = dynamic_cast<D*>(e);
cout << d << endl;
cout << f << endl;
cout << (f ? "addr" : "null") << endl;
return ;
}

从E上行转D的话,static_cast和dynamic_cast是一样的,打印出来的地址都是一样的。

delete和delete[]

正确的应该是new和delete对应,new[]和delete[]对应。

 E* e = new E();
delete e;
D* d = new D[];
delete[] d;

如果,

 E* e = new E();
delete[] e;

编译同样通过了,但是也是会core dump。

如果,

 D* d = new D[];
delete d;

编译是通过了,但是会报错,指针出错。

*** Error in `./t': munmap_chunk(): invalid pointer: 0x0000000001e8c038 ***
Aborted (core dumped)

C++盲点的更多相关文章

  1. C语言 malloc()与sizeof运算的盲点

    //malloc()与sizeof运算的盲点 #include <stdio.h> #include <stdlib.h> #include <string.h> ...

  2. 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 8.全局防护盲点的总结下篇

    0x01 背景 现在的WEB应用对SQL注入的防护基本都是判断GPC是否开启,然后使用addlashes函数对单引号等特殊字符进行转义.但仅仅使用这样的防护是存在很多盲点的,接上篇http://www ...

  3. 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 7.全局防护盲点的总结上篇

    0x01 背景 现在的WEB应用对SQL注入的防护基本都是判断GPC是否开启,然后使用addlashes函数对单引号等特殊字符进行转义.但仅仅使用这样的防护是存在很多盲点的,比如最经典的整型参数传递, ...

  4. [置顶] NS2中TCP拥塞控制仿真过程中盲点解析

    最近利用NS2做TCP拥塞控制协议的仿真,发现很多变量的方法含义都是解释的不清楚,给核心模块修改带来很多麻烦,所以决定用最准确的语言解释成员变量.方法,术语等的含义.限于个人水平,若有错误请留言指正! ...

  5. C语言盲点笔记1

    寥寥数笔,记录我的C语言盲点笔记,仅仅为以前经历过,亦有误,可交流. 1.int* a和int *a有差别吗? 没有不论什么差别,都表示a是int指针 建议这么写int *a;这样明显一点 理由例如以 ...

  6. NSRunLoop原理详解——不再有盲点

    编程最怕的就是有盲点,不确定,而runloop官网对其提及的又很少:那么看完这篇应该使你有底气很多~ RunLoop整体介绍 An event-processing loop, during whic ...

  7. OC方法交换swizzle详细介绍——不再有盲点

    原文链接:https://www.cnblogs.com/mddblog/p/11105450.html 如果对方法交换已经比较熟悉,可以跳过整体介绍,直接看常见问题部分 整体介绍 方法交换是runt ...

  8. 细数EDM营销中存在的两大盲点

    国庆节了,祝大家国庆快乐,转眼博客至今已有三年了.下面博主为大家介绍EDM营销中存在的两大盲点,供大家参考. 一是忽略用户友好.用户友好策略是Email营销成功的关键要素,具体包括内容友好策略.方式友 ...

  9. java基础盲点梳理

    类的基本成员才有默认值 finalize()并非析构,Java中没有析构,使用finalize()通常在于跨语言调用情景:比如使用C进行malloc内存分配以后,要在finalize()方法中进行fr ...

  10. 【前端盲点】DOM事件流论证CSS盒模型是否具有厚度

    前言 很久没有扯淡了,我们今天来扯淡吧. 我今天思考了一个问题,我们页面的dom树到底是如何渲染的,而CSS盒模型与javascript是否有联系,于是便想到一个问题: CSS的盒模型具有厚度么??? ...

随机推荐

  1. php中static静态关键字的使用

    php中除了常规类和方法的使用,访问控制之外,还有静态关键字static,静态变量可以是局部变量也可以是全局变量,当一个程序段执行完毕时,静态变量并没有消失,它依然存在于内存中,下次在定义时还是以前的 ...

  2. DisJSet:Wireless Network(POJ 2236)

      无线电网络 题目大意:就是地震后,所有的电脑都坏了,现在可以修复,而且要重新连成一个网络,两台电脑之间最大连接距离为D,两台电脑可以有中继电脑,按O修复电脑,按S测试两台电脑是否有链接,如果有就输 ...

  3. Window环境下Python和Django的安装

    转载地址:http://blog.csdn.net/haoni123321/article/details/7593821 1.下载python,本文使用python-2.7.2.msi 2.下载dj ...

  4. 仓鼠找sugar(洛谷 3398)

    题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...

  5. ionic react-native和native开发移动app到底那个好

    ionic react-native和native开发移动app那个好 ? 移动端开发如何选型?这里介绍一下我眼中的ionic,react-native,native 三种移动端开发选型对比.欢迎大家 ...

  6. ***linux下用cron定时执行任务的方法

    名称 : crontab  使用权限 : 所有使用者 使用方式 : crontab file [-u user]-用指定的文件替代目前的crontab. crontab-[-u user]-用标准输入 ...

  7. Xamarin.Android开发实践(十八)

    Xamarin.Android之SlidingMenu 一.前言 有位网友在评论中希望能够出个在Xamarin.Android下实现SlidingMenu效果的随笔,刚好昨天在观看官网示例项目的时候也 ...

  8. WordPress主题制作函数

    WordPress基本模板文件 一套完整的WordPress模板应至少具有如下文件: style.css: CSS(样式表)文件 index.php: 主页模板 archive.php: Archiv ...

  9. thinkphp 目录

    WWW\User\Home\Conf\settings.php 1. APP_PATH . 'Home/Conf/settings.php 2.dirname( APP_PATH ) . '/User ...

  10. 克隆或拷贝的VMware虚拟机IP问题解决

    克隆的虚拟机或是将虚拟机通过快照回到过去某个状态后,会上不了网. 如果不想看细节,可直接跳到小结部分. 问题描述: 运行service network restart时 Device eth0 doe ...