调用非静态成员函数而不创建实例

Posted

技术标签:

【中文标题】调用非静态成员函数而不创建实例【英文标题】:Calling a non-static member function without creating an instance 【发布时间】:2017-08-12 11:19:22 【问题描述】:

我是面向对象方法和 C++ 编程的新手: 我的问题是:没有实例化任何对象的类指针如何调用该类的成员函数。下面是我今天尝试的工作代码

#include <iostream>


class Base
public:
    Base()
            std::cout << "Base C-tor is called " << std::endl;
    
    void fun()
            std::cout << "Base fun() is called " << std::endl;
    
    void sorrow()
            std::cout << "Base Sorrow is called " << std::endl;
    
    ~Base()
            std::cout << "Base D-tor is called " << std::endl;
    
;


int main()

Base *b1;
b1->fun();
b1->sorrow();

下面是这段代码的输出:

Base fun() is called 
Base Sorrow is called 

【问题讨论】:

这是未定义的行为,不是工作代码 从不访问对象中任何数据成员的函数应该是静态的。你展示的设计是否有用也是值得怀疑的。编写类似 C 的函数并添加类根本不是面向对象的编程。访问未初始化的指针只是未定义的行为。编译器优化未使用的指针并不意味着您编写了有效的代码。 【参考方案1】:

尽管调用了未定义的行为,但由于编译器调用非虚拟成员函数的方式,您的代码看起来可以正常工作。对于您的 fun()sorrow() 成员函数,不会执行对实例的访问,因此函数会像正常工作一样完成(即使它的调用仍然无效)。

如果你声明你的函数virtual,崩溃的可能性会大大增加(尽管你不能保证任何未定义的行为):

virtual void fun()
        std::cout << "Base fun() is called " << std::endl;

virtual void sorrow()
        std::cout << "Base Sorrow is called " << std::endl;

调用虚函数需要访问类的实例以获取函数的位置。由于指针未初始化,代码很可能崩溃。

【讨论】:

感谢您的回答。是的 virtual ,它崩溃了。关于对对象的访问,我尝试在 fun() 中为该类的私有成员中的某个变量赋值。它打印了我分配给它的正确值。 @RahulSaraswat 虽然所有的 UB 都同样无效,但它们导致崩溃的概率是不同的。通常,与执行 CPU 指令有关的任何事情(例如函数调用)都比读取或写入垃圾内存位置(当您使用未初始化的指针访问私有变量时发生的情况)更容易导致崩溃。

以上是关于调用非静态成员函数而不创建实例的主要内容,如果未能解决你的问题,请参考以下文章

c#面向对象基础3

关于静态方法和非静态方法

C++ 非静态成员函数的非法调用

关于类中静态成员函数和静态成员变量的知识点

类静态成员变量和静态成员函数的访问方式

C++使用模板类调用非静态成员函数