当前位置: 代码迷 >> QT开发 >> 怎么在多个空间中引用一个函数,并且不破坏封装
  详细解决方案

怎么在多个空间中引用一个函数,并且不破坏封装

热度:12   发布时间:2016-04-25 04:03:19.0
如何在多个空间中引用一个函数,并且不破坏封装.
实在不想送玉,只想参观的,直接跳到最后红色就可以了.
没玉可抛,想捡砖验证是土是金的同上.

在主要砖之前,我先抛另外一块砖.(qtcreater的默认编译器)
在我的印象中,每个类的成员函数虽然是相互独立的
              例如 A::fun() 和 B::fun() 应该是没有一毛钱关系的
但是每个类的对象是没有必要重复实例化的
              例如 a1.fun() 和 a2.fun() 应该是完全相同的
如果每个类的成员函数都只初始化一次,那么理论上编译器可以知道这个成员函数的地址.但是实际上并非如此
class B
{
public:
void fun()
{
std::cout << "我的地址是" << std::endl ;
}
};

int main(int argc, char *argv[])
{
B b0;
B::fun();
while(1);
}

这段代码的编译并没有通过,也就是说编译器根本不知道B::fun()在哪,无法执行.
注意1:B没有使用this指针,也就是说即使直接使用也不会访问到非法内存.
注意2:我定义了B类的对象,也就是谁B类不会被编译器优化掉.
天,那么谁能告诉我成员函数是怎么编译的?初始化第一个对象实例一下?还是每个对象都实例一下?
此砖抛完

在编写一个c++程序的过程中我们可能遇到这种情况:
多个类或者主线程都需要用到同一个功能fun,
我们如何设计这个函数fun能让程序更加精简高效呢?

常规思维:每个类中包含一个函数 fun 在主线程中再定义一个fun
#include <iostream>
class A
{
public:
void static fun()
{
std::cout << "我的地址是" << (unsigned int)(fun) << std::endl ;
}
};
void static fun()
{
std::cout << "我的地址是" << (unsigned int)(fun) << std::endl ;
}
class B
{
public:
void static fun()
{
std::cout << "我的地址是" << (unsigned int)(fun) << std::endl ;
}
};

int main(int argc, char *argv[])
{
B b;
A a;
a.fun();
b.fun();
fun();
while(1);
}

代码中static只是为了能打印出函数的地址而已,参见前面的砖.

每个类都有自己的空间主线程使用全局空间.这样一来,编译器会形成三个函数fun.
这样虽然AB类都可以自由移植 但是一旦fun需要修改就要改三处,而且浪费了两个sizeof(fun)的内存.

只初始化一次怎么用呢?
可以在AB中声明一个全局函数来引用,但是这样一来污染了全局空间,程序的封装也被破坏了.
可以定义一个类来存放fun然后将其一个对象作为AB的静态成员,但是如此一来AB要多一个初始化的步骤.

即使是刚学c++,如此不优美的代码也严重影响了我的心情
定义一个共通算法类 
把这个函数做为一个静态函数实现

这个是一个c++群给的建议.查了一些资料,研究了一下这个方法.分享给有需要的人
#include <iostream>
class A
{
public:
void static fun()
{
std::cout << "我的地址是" << (unsigned int)(fun) << std::endl ;
}
};

int main(int argc, char *argv[])
{
A::fun();
while(1);
}


无需初始化A对象,可以直接使用fun()
只要定义了包含fun的A类,A类中将fun实现为静态函数. 在任何使用场合include了这个A.h,那么你就可以任意的使用fun了.不影响移植,多处使用一次修改,不浪费内存...

我的砖又抛完了.

------解决方案--------------------
还有 类 的 成员函数 的指针 和 普通 函数的指针 是不一样的。
但是 静态成员函数 还是 和 普通函数相似的。


#include <iostream>
using namespace std;

class A;
typedef void(A::*MyFunc)(int) ;

class A {
    public:

        A() {}
        A(MyFunc fp): fp(fp) {}
  相关解决方案