support bazel complie this project and format code.
This commit is contained in:
57
basic_content/virtual/set3/BUILD
Normal file
57
basic_content/virtual/set3/BUILD
Normal file
@@ -0,0 +1,57 @@
|
||||
# please run `bazel run //basic_content/virtual/set3:copy_consrtuct`
|
||||
# please run `bazel run //basic_content/virtual/set3:full_virde`
|
||||
# please run `bazel run //basic_content/virtual/set3:inline_virtual`
|
||||
# please run `bazel run //basic_content/virtual/set3:vir_con`
|
||||
# please run `bazel run //basic_content/virtual/set3:vir_de`
|
||||
# please run `bazel run //basic_content/virtual/set3:virtual_function`
|
||||
# please run `bazel run //basic_content/virtual/set3:virtual_function1`
|
||||
# please run `bazel run //basic_content/virtual/set3:virtual_inline`
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary")
|
||||
|
||||
cc_binary(
|
||||
name = "copy_consrtuct",
|
||||
srcs = ["copy_consrtuct.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "full_virde",
|
||||
srcs = ["full_virde.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "inline_virtual",
|
||||
srcs = ["inline_virtual.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "vir_con",
|
||||
srcs = ["vir_con.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "vir_de",
|
||||
srcs = ["vir_de.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "virtual_function",
|
||||
srcs = ["virtual_function.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "virtual_function1",
|
||||
srcs = ["virtual_function1.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "virtual_inline",
|
||||
srcs = ["virtual_inline.cpp"],
|
||||
copts = ["-std=c++11"]
|
||||
)
|
@@ -1,41 +1,29 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
class Base {
|
||||
public:
|
||||
};
|
||||
|
||||
};
|
||||
class Derived : public Base {
|
||||
public:
|
||||
Derived() { cout << "Derived created" << endl; }
|
||||
|
||||
class Derived : public Base
|
||||
{
|
||||
public:
|
||||
Derived()
|
||||
{
|
||||
cout << "Derived created" << endl;
|
||||
}
|
||||
Derived(const Derived &rhs) {
|
||||
cout << "Derived created by deep copy" << endl;
|
||||
}
|
||||
|
||||
Derived(const Derived &rhs)
|
||||
{
|
||||
cout << "Derived created by deep copy" << endl;
|
||||
}
|
||||
~Derived() { cout << "Derived destroyed" << endl; }
|
||||
};
|
||||
|
||||
~Derived()
|
||||
{
|
||||
cout << "Derived destroyed" << endl;
|
||||
}
|
||||
};
|
||||
int main() {
|
||||
Derived s1;
|
||||
|
||||
int main()
|
||||
{
|
||||
Derived s1;
|
||||
Derived s2 = s1; // Compiler invokes "copy constructor"
|
||||
// Type of s1 and s2 are concrete to compiler
|
||||
|
||||
Derived s2 = s1; // Compiler invokes "copy constructor"
|
||||
// Type of s1 and s2 are concrete to compiler
|
||||
|
||||
// How can we create Derived1 or Derived2 object
|
||||
// from pointer (reference) to Base class pointing Derived object?
|
||||
|
||||
return 0;
|
||||
}
|
||||
// How can we create Derived1 or Derived2 object
|
||||
// from pointer (reference) to Base class pointing Derived object?
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -10,30 +10,25 @@
|
||||
* @version v1
|
||||
* @date 2019-07-24
|
||||
*/
|
||||
#include<iostream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace std;
|
||||
|
||||
class base {
|
||||
public:
|
||||
base()
|
||||
{ cout<<"Constructing base \n"; }
|
||||
virtual ~base()
|
||||
{ cout<<"Destructing base \n"; }
|
||||
};
|
||||
class base {
|
||||
public:
|
||||
base() { cout << "Constructing base \n"; }
|
||||
virtual ~base() { cout << "Destructing base \n"; }
|
||||
};
|
||||
|
||||
class derived: public base {
|
||||
public:
|
||||
derived()
|
||||
{ cout<<"Constructing derived \n"; }
|
||||
~derived()
|
||||
{ cout<<"Destructing derived \n"; }
|
||||
};
|
||||
class derived : public base {
|
||||
public:
|
||||
derived() { cout << "Constructing derived \n"; }
|
||||
~derived() { cout << "Destructing derived \n"; }
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
derived *d = new derived();
|
||||
base *b = d;
|
||||
delete b;
|
||||
return 0;
|
||||
}
|
||||
int main(void) {
|
||||
derived *d = new derived();
|
||||
base *b = d;
|
||||
delete b;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,35 +1,31 @@
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
inline virtual void who()
|
||||
{
|
||||
cout << "I am Base\n";
|
||||
}
|
||||
virtual ~Base() {}
|
||||
class Base {
|
||||
public:
|
||||
inline virtual void who() { cout << "I am Base\n"; }
|
||||
virtual ~Base() {}
|
||||
};
|
||||
class Derived : public Base
|
||||
{
|
||||
public:
|
||||
inline void who() // 不写inline时隐式内联
|
||||
{
|
||||
cout << "I am Derived\n";
|
||||
}
|
||||
class Derived : public Base {
|
||||
public:
|
||||
inline void who() // 不写inline时隐式内联
|
||||
{
|
||||
cout << "I am Derived\n";
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// 此处的虚函数 who(),是通过类(Base)的具体对象(b)来调用的,编译期间就能确定了,所以它可以是内联的,但最终是否内联取决于编译器。
|
||||
Base b;
|
||||
b.who();
|
||||
int main() {
|
||||
// 此处的虚函数
|
||||
// who(),是通过类(Base)的具体对象(b)来调用的,编译期间就能确定了,所以它可以是内联的,但最终是否内联取决于编译器。
|
||||
Base b;
|
||||
b.who();
|
||||
|
||||
// 此处的虚函数是通过指针调用的,呈现多态性,需要在运行时期间才能确定,所以不能为内联。
|
||||
Base *ptr = new Derived();
|
||||
ptr->who();
|
||||
// 此处的虚函数是通过指针调用的,呈现多态性,需要在运行时期间才能确定,所以不能为内联。
|
||||
Base *ptr = new Derived();
|
||||
ptr->who();
|
||||
|
||||
// 因为Base有虚析构函数(virtual ~Base() {}),所以 delete 时,会先调用派生类(Derived)析构函数,再调用基类(Base)析构函数,防止内存泄漏。
|
||||
delete ptr;
|
||||
// 因为Base有虚析构函数(virtual ~Base() {}),所以 delete
|
||||
// 时,会先调用派生类(Derived)析构函数,再调用基类(Base)析构函数,防止内存泄漏。
|
||||
delete ptr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -9,5 +9,5 @@
|
||||
* @date 2019-07-24
|
||||
*/
|
||||
|
||||
virtual static void fun() { }
|
||||
static void fun() const { }
|
||||
virtual static void fun() {}
|
||||
static void fun() const {}
|
||||
|
@@ -1,206 +1,158 @@
|
||||
/**
|
||||
* @file vir_con.cpp
|
||||
* @brief 构造函数不可以声明为虚函数。同时除了inline之外,构造函数不允许使用其它任何关键字。
|
||||
* @brief
|
||||
* 构造函数不可以声明为虚函数。同时除了inline之外,构造函数不允许使用其它任何关键字。
|
||||
*
|
||||
* 为什么构造函数不可以为虚函数?
|
||||
*
|
||||
* 尽管虚函数表vtable是在编译阶段就已经建立的,但指向虚函数表的指针vptr是在运行阶段实例化对象时才产生的。 如果类含有虚函数,编译器会在构造函数中添加代码来创建vptr。 问题来了,如果构造函数是虚的,那么它需要vptr来访问vtable,可这个时候vptr还没产生。 因此,构造函数不可以为虚函数。
|
||||
* 尽管虚函数表vtable是在编译阶段就已经建立的,但指向虚函数表的指针vptr是在运行阶段实例化对象时才产生的。
|
||||
* 如果类含有虚函数,编译器会在构造函数中添加代码来创建vptr。
|
||||
* 问题来了,如果构造函数是虚的,那么它需要vptr来访问vtable,可这个时候vptr还没产生。
|
||||
* 因此,构造函数不可以为虚函数。
|
||||
* 我们之所以使用虚函数,是因为需要在信息不全的情况下进行多态运行。而构造函数是用来初始化实例的,实例的类型必须是明确的。
|
||||
* 因此,构造函数没有必要被声明为虚函数。
|
||||
* 尽管构造函数不可以为虚函数,但是有些场景下我们确实需要 “Virtual Copy Constructor”。 “虚复制构造函数”的说法并不严谨,其只是一个实现了对象复制的功能的类内函数。 举一个应用场景,比如剪切板功能。 复制内容作为基类,但派生类可能包含文字、图片、视频等等。 我们只有在程序运行的时候才知道我们需要复制的具体是什么类型的数据。
|
||||
* 尽管构造函数不可以为虚函数,但是有些场景下我们确实需要 “Virtual Copy
|
||||
* Constructor”。
|
||||
* “虚复制构造函数”的说法并不严谨,其只是一个实现了对象复制的功能的类内函数。
|
||||
* 举一个应用场景,比如剪切板功能。
|
||||
* 复制内容作为基类,但派生类可能包含文字、图片、视频等等。
|
||||
* 我们只有在程序运行的时候才知道我们需要复制的具体是什么类型的数据。
|
||||
*
|
||||
* @author 光城
|
||||
* @version v1
|
||||
* @date 2019-07-24
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
//// LIBRARY SRART
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Base() { }
|
||||
//// LIBRARY SRART
|
||||
class Base {
|
||||
public:
|
||||
Base() {}
|
||||
|
||||
virtual // Ensures to invoke actual object destructor
|
||||
~Base() { }
|
||||
virtual // Ensures to invoke actual object destructor
|
||||
~Base() {}
|
||||
|
||||
virtual void ChangeAttributes() = 0;
|
||||
virtual void ChangeAttributes() = 0;
|
||||
|
||||
// The "Virtual Constructor"
|
||||
static Base *Create(int id);
|
||||
// The "Virtual Constructor"
|
||||
static Base *Create(int id);
|
||||
|
||||
// The "Virtual Copy Constructor"
|
||||
virtual Base *Clone() = 0;
|
||||
};
|
||||
// The "Virtual Copy Constructor"
|
||||
virtual Base *Clone() = 0;
|
||||
};
|
||||
|
||||
class Derived1 : public Base
|
||||
{
|
||||
public:
|
||||
Derived1()
|
||||
{
|
||||
cout << "Derived1 created" << endl;
|
||||
}
|
||||
class Derived1 : public Base {
|
||||
public:
|
||||
Derived1() { cout << "Derived1 created" << endl; }
|
||||
|
||||
Derived1(const Derived1& rhs)
|
||||
{
|
||||
cout << "Derived1 created by deep copy" << endl;
|
||||
}
|
||||
Derived1(const Derived1 &rhs) {
|
||||
cout << "Derived1 created by deep copy" << endl;
|
||||
}
|
||||
|
||||
~Derived1()
|
||||
{
|
||||
cout << "~Derived1 destroyed" << endl;
|
||||
}
|
||||
~Derived1() { cout << "~Derived1 destroyed" << endl; }
|
||||
|
||||
void ChangeAttributes()
|
||||
{
|
||||
cout << "Derived1 Attributes Changed" << endl;
|
||||
}
|
||||
void ChangeAttributes() { cout << "Derived1 Attributes Changed" << endl; }
|
||||
|
||||
Base *Clone()
|
||||
{
|
||||
return new Derived1(*this);
|
||||
}
|
||||
};
|
||||
Base *Clone() { return new Derived1(*this); }
|
||||
};
|
||||
|
||||
class Derived2 : public Base
|
||||
{
|
||||
public:
|
||||
Derived2()
|
||||
{
|
||||
cout << "Derived2 created" << endl;
|
||||
}
|
||||
class Derived2 : public Base {
|
||||
public:
|
||||
Derived2() { cout << "Derived2 created" << endl; }
|
||||
|
||||
Derived2(const Derived2& rhs)
|
||||
{
|
||||
cout << "Derived2 created by deep copy" << endl;
|
||||
}
|
||||
Derived2(const Derived2 &rhs) {
|
||||
cout << "Derived2 created by deep copy" << endl;
|
||||
}
|
||||
|
||||
~Derived2()
|
||||
{
|
||||
cout << "~Derived2 destroyed" << endl;
|
||||
}
|
||||
~Derived2() { cout << "~Derived2 destroyed" << endl; }
|
||||
|
||||
void ChangeAttributes()
|
||||
{
|
||||
cout << "Derived2 Attributes Changed" << endl;
|
||||
}
|
||||
void ChangeAttributes() { cout << "Derived2 Attributes Changed" << endl; }
|
||||
|
||||
Base *Clone()
|
||||
{
|
||||
return new Derived2(*this);
|
||||
}
|
||||
};
|
||||
Base *Clone() { return new Derived2(*this); }
|
||||
};
|
||||
|
||||
class Derived3 : public Base
|
||||
{
|
||||
public:
|
||||
Derived3()
|
||||
{
|
||||
cout << "Derived3 created" << endl;
|
||||
}
|
||||
class Derived3 : public Base {
|
||||
public:
|
||||
Derived3() { cout << "Derived3 created" << endl; }
|
||||
|
||||
Derived3(const Derived3& rhs)
|
||||
{
|
||||
cout << "Derived3 created by deep copy" << endl;
|
||||
}
|
||||
Derived3(const Derived3 &rhs) {
|
||||
cout << "Derived3 created by deep copy" << endl;
|
||||
}
|
||||
|
||||
~Derived3()
|
||||
{
|
||||
cout << "~Derived3 destroyed" << endl;
|
||||
}
|
||||
~Derived3() { cout << "~Derived3 destroyed" << endl; }
|
||||
|
||||
void ChangeAttributes()
|
||||
{
|
||||
cout << "Derived3 Attributes Changed" << endl;
|
||||
}
|
||||
void ChangeAttributes() { cout << "Derived3 Attributes Changed" << endl; }
|
||||
|
||||
Base *Clone()
|
||||
{
|
||||
return new Derived3(*this);
|
||||
}
|
||||
};
|
||||
Base *Clone() { return new Derived3(*this); }
|
||||
};
|
||||
|
||||
// We can also declare "Create" outside Base.
|
||||
// But is more relevant to limit it's scope to Base
|
||||
Base *Base::Create(int id)
|
||||
{
|
||||
// Just expand the if-else ladder, if new Derived class is created
|
||||
// User need not be recompiled to create newly added class objects
|
||||
// We can also declare "Create" outside Base.
|
||||
// But is more relevant to limit it's scope to Base
|
||||
Base *Base::Create(int id) {
|
||||
// Just expand the if-else ladder, if new Derived class is created
|
||||
// User need not be recompiled to create newly added class objects
|
||||
|
||||
if( id == 1 )
|
||||
{
|
||||
return new Derived1;
|
||||
}
|
||||
else if( id == 2 )
|
||||
{
|
||||
return new Derived2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Derived3;
|
||||
}
|
||||
}
|
||||
//// LIBRARY END
|
||||
if (id == 1) {
|
||||
return new Derived1;
|
||||
} else if (id == 2) {
|
||||
return new Derived2;
|
||||
} else {
|
||||
return new Derived3;
|
||||
}
|
||||
}
|
||||
//// LIBRARY END
|
||||
|
||||
//// UTILITY SRART
|
||||
class User
|
||||
{
|
||||
public:
|
||||
User() : pBase(0)
|
||||
{
|
||||
// Creates any object of Base heirarchey at runtime
|
||||
//// UTILITY SRART
|
||||
class User {
|
||||
public:
|
||||
User() : pBase(0) {
|
||||
// Creates any object of Base heirarchey at runtime
|
||||
|
||||
int input;
|
||||
int input;
|
||||
|
||||
cout << "Enter ID (1, 2 or 3): ";
|
||||
cin >> input;
|
||||
cout << "Enter ID (1, 2 or 3): ";
|
||||
cin >> input;
|
||||
|
||||
while( (input != 1) && (input != 2) && (input != 3) )
|
||||
{
|
||||
cout << "Enter ID (1, 2 or 3 only): ";
|
||||
cin >> input;
|
||||
}
|
||||
while ((input != 1) && (input != 2) && (input != 3)) {
|
||||
cout << "Enter ID (1, 2 or 3 only): ";
|
||||
cin >> input;
|
||||
}
|
||||
|
||||
// Create objects via the "Virtual Constructor"
|
||||
pBase = Base::Create(input);
|
||||
}
|
||||
// Create objects via the "Virtual Constructor"
|
||||
pBase = Base::Create(input);
|
||||
}
|
||||
|
||||
~User()
|
||||
{
|
||||
if( pBase )
|
||||
{
|
||||
delete pBase;
|
||||
pBase = 0;
|
||||
}
|
||||
}
|
||||
~User() {
|
||||
if (pBase) {
|
||||
delete pBase;
|
||||
pBase = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Action()
|
||||
{
|
||||
// Duplicate current object
|
||||
Base *pNewBase = pBase->Clone();
|
||||
void Action() {
|
||||
// Duplicate current object
|
||||
Base *pNewBase = pBase->Clone();
|
||||
|
||||
// Change its attributes
|
||||
pNewBase->ChangeAttributes();
|
||||
// Change its attributes
|
||||
pNewBase->ChangeAttributes();
|
||||
|
||||
// Dispose the created object
|
||||
delete pNewBase;
|
||||
}
|
||||
// Dispose the created object
|
||||
delete pNewBase;
|
||||
}
|
||||
|
||||
private:
|
||||
Base *pBase;
|
||||
};
|
||||
private:
|
||||
Base *pBase;
|
||||
};
|
||||
|
||||
//// UTILITY END
|
||||
//// UTILITY END
|
||||
|
||||
//// Consumer of User (UTILITY) class
|
||||
int main()
|
||||
{
|
||||
User *user = new User();
|
||||
//// Consumer of User (UTILITY) class
|
||||
int main() {
|
||||
User *user = new User();
|
||||
|
||||
user->Action();
|
||||
|
||||
delete user;
|
||||
}
|
||||
user->Action();
|
||||
|
||||
delete user;
|
||||
}
|
||||
|
@@ -10,32 +10,27 @@
|
||||
* @date 2019-07-24
|
||||
*/
|
||||
|
||||
// CPP program without virtual destructor
|
||||
// causing undefined behavior
|
||||
#include<iostream>
|
||||
// CPP program without virtual destructor
|
||||
// causing undefined behavior
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace std;
|
||||
|
||||
class base {
|
||||
public:
|
||||
base()
|
||||
{ cout<<"Constructing base \n"; }
|
||||
~base()
|
||||
{ cout<<"Destructing base \n"; }
|
||||
};
|
||||
class base {
|
||||
public:
|
||||
base() { cout << "Constructing base \n"; }
|
||||
~base() { cout << "Destructing base \n"; }
|
||||
};
|
||||
|
||||
class derived: public base {
|
||||
public:
|
||||
derived()
|
||||
{ cout<<"Constructing derived \n"; }
|
||||
~derived()
|
||||
{ cout<<"Destructing derived \n"; }
|
||||
};
|
||||
class derived : public base {
|
||||
public:
|
||||
derived() { cout << "Constructing derived \n"; }
|
||||
~derived() { cout << "Destructing derived \n"; }
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
derived *d = new derived();
|
||||
base *b = d;
|
||||
delete b;
|
||||
return 0;
|
||||
}
|
||||
int main(void) {
|
||||
derived *d = new derived();
|
||||
base *b = d;
|
||||
delete b;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -2,32 +2,32 @@
|
||||
* @file virtual_function.cpp
|
||||
* @brief 虚函数可以被私有化,但有一些细节需要注意。
|
||||
* 基类指针指向继承类对象,则调用继承类对象的函数;
|
||||
* int main()必须声明为Base类的友元,否则编译失败。 编译器报错: ptr无法访问私有函数。
|
||||
* 当然,把基类声明为public, 继承类为private,该问题就不存在了。----> 见另外一个例子!
|
||||
* int main()必须声明为Base类的友元,否则编译失败。 编译器报错:
|
||||
* ptr无法访问私有函数。 当然,把基类声明为public,
|
||||
* 继承类为private,该问题就不存在了。----> 见另外一个例子!
|
||||
* @author 光城
|
||||
* @version v1
|
||||
* @date 2019-07-24
|
||||
*/
|
||||
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class Derived;
|
||||
class Derived;
|
||||
|
||||
class Base {
|
||||
private:
|
||||
virtual void fun() { cout << "Base Fun"; }
|
||||
friend int main();
|
||||
};
|
||||
class Base {
|
||||
private:
|
||||
virtual void fun() { cout << "Base Fun"; }
|
||||
friend int main();
|
||||
};
|
||||
|
||||
class Derived: public Base {
|
||||
public:
|
||||
void fun() { cout << "Derived Fun"; }
|
||||
};
|
||||
class Derived : public Base {
|
||||
public:
|
||||
void fun() { cout << "Derived Fun"; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Base *ptr = new Derived;
|
||||
ptr->fun();
|
||||
return 0;
|
||||
int main() {
|
||||
Base *ptr = new Derived;
|
||||
ptr->fun();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,22 +1,21 @@
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class Derived;
|
||||
class Derived;
|
||||
|
||||
class Base {
|
||||
public:
|
||||
virtual void fun() { cout << "Base Fun"; }
|
||||
// friend int main();
|
||||
};
|
||||
class Base {
|
||||
public:
|
||||
virtual void fun() { cout << "Base Fun"; }
|
||||
// friend int main();
|
||||
};
|
||||
|
||||
class Derived: public Base {
|
||||
private:
|
||||
void fun() { cout << "Derived Fun"; }
|
||||
};
|
||||
class Derived : public Base {
|
||||
private:
|
||||
void fun() { cout << "Derived Fun"; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Base *ptr = new Derived;
|
||||
ptr->fun();
|
||||
return 0;
|
||||
int main() {
|
||||
Base *ptr = new Derived;
|
||||
ptr->fun();
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file virtual_inline.cpp
|
||||
* @brief 通常类成员函数都会被编译器考虑是否进行内联。
|
||||
* @brief 通常类成员函数都会被编译器考虑是否进行内联。
|
||||
* 但通过基类指针或者引用调用的虚函数必定不能被内联。
|
||||
* 当然,实体对象调用虚函数或者静态调用时可以被内联,虚析构函数的静态调用也一定会被内联展开。
|
||||
* @author 光城
|
||||
@@ -8,37 +8,28 @@
|
||||
* @date 2019-07-24
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
virtual void who()
|
||||
{
|
||||
cout << "I am Base\n";
|
||||
}
|
||||
};
|
||||
class Derived: public Base
|
||||
{
|
||||
public:
|
||||
void who()
|
||||
{
|
||||
cout << "I am Derived\n";
|
||||
}
|
||||
};
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
class Base {
|
||||
public:
|
||||
virtual void who() { cout << "I am Base\n"; }
|
||||
};
|
||||
class Derived : public Base {
|
||||
public:
|
||||
void who() { cout << "I am Derived\n"; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// note here virtual function who() is called through
|
||||
// object of the class (it will be resolved at compile
|
||||
// time) so it can be inlined.
|
||||
Base b;
|
||||
b.who();
|
||||
int main() {
|
||||
// note here virtual function who() is called through
|
||||
// object of the class (it will be resolved at compile
|
||||
// time) so it can be inlined.
|
||||
Base b;
|
||||
b.who();
|
||||
|
||||
// Here virtual function is called through pointer,
|
||||
// so it cannot be inlined
|
||||
Base *ptr = new Derived();
|
||||
ptr->who();
|
||||
// Here virtual function is called through pointer,
|
||||
// so it cannot be inlined
|
||||
Base *ptr = new Derived();
|
||||
ptr->who();
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user