非virtual函数,用指针进行upcast】的更多相关文章

void print_func(A* p) { p -> print(); } int main() { A a(); B b(,); //a.print(); //b.print(); print_func(&a);// 这两个调用的都是a的print print_func(&b); a = b; a.print(); ; } B*这个类型会被当成A*来访问.所以调用的是A的print. 因为这个寻址,不是用虚表寻址,而是编译器做的静态绑定.…
下面讨论的都是类的非静态成员函数. 类成员函数指针的声明及调用: 1 2 3 4 5 6 7 //pr是指向Base类里的非静态成员函数的指针 //其行参为(int, int),返回值为void void (Base::*pr)(int, int);   //需通过对象调用 //object是Base类的一个对象或指针(可多态) ( object->*pr)( _r, _c) 而其实质和普通的指针也有区别: //下面是隐藏的代码是相关类型的定义 1 2 3 4 5 6 7 8 9 10 11 1…
1. 数据成员指针 对于普通指针变量来说,其值是它所指向的地址,0表示空指针. 而对于数据成员指针变量来说,其值是数据成员所在地址相对于对象起始地址的偏移值,空指针用-1表示.例: 代码示例: struct X { int a; int b; }; #define VALUE_OF_PTR(p) (*(long*)&p) int main() { ; // VALUE_OF_PTR(p) == -1 p = &X::a; // VALUE_OF_PTR(p) == 0 p = &X…
原文:C/C++杂记:深入理解数据成员指针.函数成员指针 1. 数据成员指针 对于普通指针变量来说,其值是它所指向的地址,0表示空指针.而对于数据成员指针变量来说,其值是数据成员所在地址相对于对象起始地址的偏移值,空指针用-1表示.例: 代码示例:   2. 函数成员指针 函数成员指针与普通函数指针相比,其size为普通函数指针的两倍(x64下为16字节),分为:ptr和adj两部分. (1) 非虚函数成员指针 ptr部分内容为函数指针(指向一个全局函数,该函数的第一个参数为this指针),ad…
#include<iostream> #include<string> using namespace std; class Base { public: Base(){} ~Base(){} public: virtual void f1(int x){ cout << "baseclass: f1() " << x << endl; } virtual void f2()final{ cout << "…
作为通常的原则,如果一个类定义了虚函数,那么它的析构函数就应当是virtual的.因为定义了虚函数则隐含着:这个类会被继承,并且会通过基类的指针指向子类对象,从而得到多态性.   这个类可能会被继承,并且会通过基类的指针指向子类对象”,因此基类的析构函数是否为虚将决定子类的对象是否被析构 示例代码: #include <iostream.h> struct A { virtual ~A() {cout<<"~A()\n";} }; struct B: publi…
http://blog.csdn.net/freeboy1015/article/details/7635012 为什么内联函数,构造函数,静态成员函数不能为virtual函数? 1> 内联函数 内联函数是在编译时期展开,而虚函数的特性是运行时才动态联编,所以两者矛盾,不能定义内联函数为虚函数. 2> 构造函数 构造函数用来创建一个新的对象,而虚函数的运行是建立在对象的基础上,在构造函数执行时,对象尚未形成,所以不能将构造函数定义为虚函数. 3> 静态成员函数 静态成员函数属于一个类而非…
游戏中的人物伤害值计算问题. (一)方法(1):一般来讲能够使用虚函数的方法: class GameCharacter { public: virtual int healthValue() const; //返回人物的体力值,派生类能够做出改动 ... }; 这确实是一个显而易见的设计选择.但由于这种设计过于显而易见,可能不会对其他可选方法给予足够的关注.我们来考虑一些处理这个问题的其他方法. (二)方法(2):使用NVI方法,在基类中使用一个公有的普通函数调用私有的虚函数. class Ga…
1. 为什么不要重新定义继承而来的非虚函数——实际论证 假设我告诉你一个类D public继承类B,在类B中定义了一个public成员函数mf.Mf的参数和返回类型并不重要,所以假设它们都是void.实现如下: class B { public: void mf(); ... }; lass D: public B { ... } 我们不需要了解B,D或者mf的任何细节,考虑一个类型D的对象x, D x; // x is an object of type D 你会感到很吃惊,如果下面的语句:…
在C++中,有四种选择可以替代virtual函数的功能: 1.non-virtual interface(NVI)手法,这是一种template method模式.它以public non-virtual成员函数包含较低访问性的virtual函数.对于子类而言,子类只需重定义私有的virtual函数即可. 2.将virtual函数替换为"函数指针成员变量",这是Strategy模式的一种表现形式.这种方案的优点在于,将类和行为分离(比如相同的类的不同对象可以具有不同的行为):缺点在于,…