C++类保护函数外部调用

一、protected虚函数

class CMyView : public CView

{

protected:
 virtual void OnDraw(CDC* pDC);

};

 

CMyView* pMyView;

pMyView->OnDraw(NULL);//编译不通过

解决方法:

1、protected:修改为public:

2、

typedef void (CView::*pFOnDraw)(CDC* pDC);

获取到CMyView::OnDraw的函数地址

 pFOnDraw callOnDraw = (pFOnDraw)&CMyView::OnDraw;//编译不通过,只能在CView子类内部获取

然后就可以这样调用

(pMyView->*callOnDraw)(pDC);

 

3、C++嵌入汇编

 __asm
  {

  mov ecx,pMyView
   call CMyView::OnDraw

}

<think>嗯,用户问C++能不能调用外部函数。我需要先确认问题的核心是什么。用户可能刚开始学C++,对的成员函数外部函数的关系不太清楚。首先,我得回忆一下C++的基本概念,可以调用外部函数吗?当然可以,无论是全局函数、其他的静态成员函数,还是命名空间中的函数都可以调用。但可能需要具体例子来说明。 接下来,用户可能想知道如何调用,以及有哪些注意事项。比如权限问题,是否需要头文件包含,或者友元声明。我应该分情况说明,比如在成员函数内部调用外部函数,或者作为友元函数的情况。静态成员函数和普通成员函数的区别也需要提到。 然后,要确保举的例子正确,符合C++语法。例如,在的成员函数调用一个全局函数,或者在外定义函数,然后在的方法中使用。同时,可能要注意作用域和可见性,比如函数声明的位置,是否在定义之前,或者是否需要前置声明。 另外,用户可能对静态函数和普通函数调用方式有疑问,比如是否需要实例化对象才能调用。静态成员函数可以直接通过调用,而普通成员函数需要对象实例。而外部函数如果是全局的,可以直接在的成员函数中使用。 还有,是否需要使用命名空间?比如外部函数在某个命名空间里,调用时需要带上命名空间前缀。或者友元函数的例子,友元函数可以访问的私有成员,这种情况下如何声明和定义。 可能用户的实际应用场景是什么?比如他们可能在写一个,需要用到某个库里的函数,或者自己定义的辅助函数。这时候,如何正确地在的方法中调用这些外部函数,需要注意链接和包含头文件的问题。 另外,错误处理也可能是一个点,比如如果外部函数没有被正确声明或定义,会导致编译错误。这时候需要检查函数的声明和定义是否可见,链接是否正确。 总结一下,回答的结构应该是先明确回答“可以”,然后分情况讨论不同的调用方式,给出具体例子,最后可能提到注意事项,比如作用域、友元声明、静态函数等。确保用户能够理解不同的调用场景和正确的方法。</think>当然可以!C++ 可以通过多种方式调用外部函数。以下是具体说明和示例: --- ### 一、直接调用全局函数 **原理**:在的成员函数中直接调用全局作用域中定义的函数。 ```cpp #include <iostream> using namespace std; // 外部全局函数 void printMessage() { cout << "Hello from global function!" << endl; } class MyClass { public: void callExternal() { printMessage(); // 直接调用外部全局函数 } }; int main() { MyClass obj; obj.callExternal(); // 输出:Hello from global function! return 0; } ``` --- ### 二、调用其他的静态成员函数 **原理**:静态成员函数属于本身,无需实例化对象即可调用。 ```cpp class Utility { public: static int add(int a, int b) { return a + b; } }; class Calculator { public: void calculate() { int result = Utility::add(3, 5); // 调用其他的静态函数 cout << "Result: " << result << endl; } }; ``` --- ### 三、通过函数指针调用 **原理**:将外部函数地址传递给成员函数,实现动态调用。 ```cpp void externalFunc() { cout << "Function pointer called!" << endl; } class CallbackHandler { public: void setCallback(void (*func)()) { m_func = func; } void execute() { m_func(); } private: void (*m_func)() = nullptr; }; // 使用示例: CallbackHandler handler; handler.setCallback(externalFunc); handler.execute(); // 输出:Function pointer called! ``` --- ### 四、调用命名空间中的函数 **原理**:通过命名空间限定符访问外部函数。 ```cpp namespace MathUtils { double square(double x) { return x * x; } } class Geometry { public: void computeArea() { double area = MathUtils::square(4.0); // 调用命名空间中的函数 cout << "Area: " << area << endl; } }; ``` --- ### 五、友元函数(特殊场景) **原理**:声明友元函数后,外部函数可以直接访问的私有成员。 ```cpp class SecretBox { private: int secret = 42; // 声明友元函数 friend void revealSecret(SecretBox& box); }; // 外部友元函数定义 void revealSecret(SecretBox& box) { cout << "Secret is: " << box.secret << endl; // 直接访问私有成员 } // 使用示例: SecretBox box; revealSecret(box); // 输出:Secret is: 42 ``` --- ### 注意事项 1. **作用域可见性**:确保外部函数调用前已声明或定义。 2. **头文件管理**:若外部函数定义在其他文件中,需包含对应的头文件。 3. **链接问题**:确保函数实现最终能被链接器找到(避免未定义错误)。 如果有具体使用场景,可以进一步分析最佳实践!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值