1. C++类中各种成员函数
1.1 非静态(非static
)、非虚(非virtual
)成员函数
这是最常规的一种成员函数,必须通过其绑定的对象或指针调用。
// test20.cpp |
|
#include <cstdio> |
|
class Test20 { |
|
public: |
|
explicit |
|
Test20(int i) |
|
: m_i(i) |
|
{} |
|
int getInt() const { return m_i; } |
|
void setInt(int i) { m_i = i; } |
|
private: |
|
int m_i; |
|
}; |
|
int main() { |
|
Test20 t20(1); |
|
std::printf("%d/n", t20.getInt()); |
|
t20.setInt(2); |
|
std::printf("%d/n", t20.getInt()); |
|
Test20* pt20 = &t20; |
|
pt20->setInt(3); |
|
std::printf("%d/n", t20.getInt()); |
|
} |
|
// Output: |
|
// 1 |
|
// 2 |
|
// 3 |
实际上,编译器会将这种成员函数改写为非成员函数,并在函数的参数列表前面加一个类型为Test20* const
的形式参数(如果成员函数加了const
关键词则形参类型为const Test20* const
),参数名为this
。而且,在成员函数内所有对于该类所有的成员函数、成员变量的操作都通过this
指针来进行。以Test20::setInt
为例,改写之后就变成了:
void setInt(Test20* const this, int i) { |
|
this->m_i = i; |
|
} |
同时,为了放置名字冲突,编译器还会对函数的名字进行修饰,包括在前面添加其命名空间信息,其后添加参数信息等,这里就不详细展开了。
1.2 虚函数
为了支持多态,C++引入了虚函数这一概念。对于虚函数的调用会转化为对于虚函数表中某一表项内填写的函数指针的调用。
如下面的调用:
ptr->virtalFunc(); |
实际上会转化为:
// C++伪码 |
|
(ptr->vptr[1])(ptr); |
其中ptr
为指向某一对象的指针,virtualFunc
为对象的某个virtual
的成员函数,vptr
为其虚函数表,1
为virtualFunc
这个虚函数在虚函数表中的下标。
注意,只有使用指针和引用调用虚函数时才会表现出多态性(也就是从虚函数表中取函数的实际地址然后调用),而使用对象调用一个虚函数,即便其被声明为一个虚函数,也只是被当作常规函数调用,不会展现多态性(也就是不会从虚函数表中取得实际函数地址)。
// test21.cpp |
|
#include <cstdio> |
|
class Test21 { |
|
public: |
|
explicit |
|
Test21(int i) |
|
: m_i(i) |
|
{} |
|
virtual |
|
int getInt() { return m_i; } |
|
private: |
|
int m_i; |
|
}; |
|
void call(Test21& t21) { |
|
int i = t21.getInt(); |
|
} |
|
int main() { |
|
Test21 t21(1); |
|
int i = t21.getInt(); |
|
call(t21); |
|
Test21* pt21 = &t21; |
|
i = pt21->getInt(); |
|
} |
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/293364.html