C++ 类指针作为函数参数访问成员函数

C++ 类指针作为函数参数访问成员函数,c++,oop,design-patterns,C++,Oop,Design Patterns,我想知道下面这行代码在C++17中是否合法 function(pClass->Class_member_function()); pClass是类指针,class\u member\u函数是类成员函数。 pClass通过->运算符访问Class\u member\u函数,并将其传递给全局函数函数 允许这样做吗?任何有用的提示都将不胜感激 编辑: 我问了以下关于编程作业的问题。我对编程这门学科还是个新手,我意识到我需要寻求帮助。请对我耐心点 对于这项任务,我必须使用工厂方法设计模式和非成员

我想知道下面这行代码在C++17中是否合法

function(pClass->Class_member_function());
pClass
是类指针,
class\u member\u函数
是类成员函数。
pClass
通过
->
运算符访问Class\u member\u函数,并将其传递给全局函数
函数

允许这样做吗?任何有用的提示都将不胜感激

编辑: 我问了以下关于编程作业的问题。我对编程这门学科还是个新手,我意识到我需要寻求帮助。请对我耐心点

对于这项任务,我必须使用工厂方法设计模式和非成员功能的虚拟化(通过委托给虚拟成员功能)实现虚拟构建

construct()函数将根据选择创建格式化程序对象(文本、标记或Html),并创建标题、段落和块引号。全局函数save()将文本元素保存到流中。包含的文件是唯一允许使用的文件

感谢前面回答的人

下面的main.cpp文件包含我的教授提供的驱动程序代码:

#include "MemoryAlloc.h"
#include "Constructor.h"

void process(IFormatterElement* const element)
{
    if (element)
    {
        try
        {
            if (ISavable* const savable = dynamic_cast<ISavable* const>(element))
            {
                save(*savable, std::cout);
            }
            delete element;
        }
        catch (...)
        {
            delete element;
            throw;
        }
    }
}

int main()
{
    std::cerr << "Choose a formatter:\n";
    std::vector<std::string> options = get_options();
    for (size_t i = 0; i < options.size(); ++i)
    {
        std::cerr << "\t" << (i + 1) << ". " << options[i] << "\n";
    }
    
    std::cerr
    << "\tother to exit\n"
    << "Your choice: ";
    
    int selected_option;
    if (std::cin >> selected_option)
    {
        if (IFormatterFactory* factory = construct(--selected_option))
        {
            std::cerr << "\nYou chose \"" << options[selected_option] << "\"." << std::endl;
            try
            {
                process(factory->create_begin());
                process(factory->create_header1("Assignment result"));
                process(factory->create_paragraph("This file represents an assignment result."));
                process(factory->create_header2("Initial paragraph"));
                process(factory->create_paragraph("This is the first paragraph of the result file."));
                process(factory->create_header2("Final paragraph"));
                process(factory->create_paragraph("This is the second paragraph of the result file."));
                process(factory->create_blockquote("This is a quote."));
                process(factory->create_paragraph("This is the third paragraph of the result file."));
                process(factory->create_paragraph("This is the last paragraph of the result file."));
                process(factory->create_end());
            }
            catch (...)
            {
                std::cerr << "An exception has been thrown!" << std::endl;
            }
            delete factory;
        }
        else
        {
            std::cerr << "Exiting..." << std::endl;
        }
    }
}
接口类IFormatterfactory.h,以支持我定义的main()中所需的操作

#ifndef _IFORMATTERELEMENT_H_
#define _IFORMATTERELEMENT_H_

class IFormatterElement
{
public:
    virtual ~IFormatterElement() = default;  
};

#endif // _IFORMATTERELEMENT_H_
#ifndef _IFORMATTERFACTORY_H_
#define _IFORMATTERFACTORY_H_

#include <string>

#include "IFormatterElement.h"

class IFormatterFactory : public IFormatterElement
{
public:
    virtual IFormatterFactory* create_begin() = 0;
    virtual IFormatterFactory* create_end() = 0;
    virtual IFormatterFactory* create_header1(const std::string& text) = 0;
    virtual IFormatterFactory* create_header2(const std::string& text) = 0;
    virtual IFormatterFactory* create_paragraph(const std::string& text) = 0;
    virtual IFormatterFactory* create_blockquote(const std::string& text) = 0;
};

#endif // _IFORMATTERFACTORY_H_
下面是我对Constructor.cpp的实现

#include "Constructor.h"
#include "Text.h"
#include "Markdown.h"
#include "Html.h"

std::vector<std::string> get_options()
{
    std::vector<std::string> formatters;
    formatters.push_back("Text");
    formatters.push_back("Markdown");
    formatters.push_back("Html");
    return formatters;
}

IFormatterFactory* construct(int selected_option)
{
    if(selected_option == 0)
        return new Text;
    
    if(selected_option == 1)
        return new Markdown;
    
    else
        return new Html;
}

void save(ISavable& savable, std::ostream& stream)
{
    savable.save(stream);
}
我认为这个错误的原因是调用
进程(工厂>创建_begin())在main()中,由我的教授给出,我无法更改


我真的被困在这个时刻了。我无法联系到我的教授寻求帮助,所以我向在线社区寻求帮助。成员函数
create_begin()
在我的文本、标记和Html类中是否执行错误?

在您的叙述中,声明:

function(pClass->class_member_function());
如果至少:

  • class\u member\u function()
  • 返回一个类型该类型对应于
    函数()的参数所需的类型或可以隐式转换的类型
基于参数类型,可以应用其他条件(例如,如果是值类型,则该类型必须是可复制构造的)

<>这是在C++ 20,C++ 17中的真实情况,并且可能是Stroustrup 1986版中公开的第一个C++版本。 下面是一个演示有效和无效案例的小演示:

void function (MyResultClass x) { 
    std::cout<<"YES, IT WORKS"<<std::endl; 
}

class MyClass {
public: 
    MyResultClass class_member_function() {return MyResultClass{}; } 
    MyCompatibleClass class_member_function_compatible() {return MyCompatibleClass{}; } 
    MyIncompatibleClass class_member_function_incompatible() {return MyIncompatibleClass{}; } 
private: 
    MyResultClass private_class_member_function() {return MyResultClass{}; } 
};

int main() {
    MyClass *pClass=new MyClass();
    function(pClass->class_member_function());
    function(pClass->class_member_function_compatible());
    // function(pClass->class_member_function_incompatible());  // OUCH!!!
    // function(pClass->private_class_member_function());  //OUCH!!!
    return 0;
}
void函数(MyResultClass x){
std::coutprivate_class_member_function());//哎哟!!!
返回0;
}

这一行的内容如下:

 function(pClass->Class_member_function());
             // ^^ dereference pClass
             //   ^^ access member Class_member_function
             //                        ^^ call it
       // pass result to function
启用上述功能的一种方法是

struct P {
     int Class_member_function() { return 42; }
};
void function( int x) {}
函数
未将成员函数作为参数!在代码中调用成员函数,并将结果值传递给
函数
。鉴于我的实施,上述行与

function(42);

可以将指向方法的指针传递给函数,但这不是您的代码所做的。

是的,代码没有问题。这似乎是合法的,尽管它取决于上下文。将成员函数的结果传递给另一个函数。但是您想要实现什么?调用一个函数并将返回值传递给另一个函数时,
function()
expect需要哪种参数类型。再合法不过了。“它被传递给一个全局函数”-好吧,这读起来好像你认为它是成员函数本身。所以这不是真的。执行成员函数,然后将结果输入自由函数。
Choose a formatter:
    1. Text
    2. Markdown
    3. Html
    other to exit
Your choice: 3

You chose "Html".
<!doctype html>
<html lang=en>
<style>blockquote { border-left: 4px solid #d0d0d0; padding: 4px; }</style>
<head>  <meta charset=utf-8>
        <title>Result</title></head>
<body>

Thread 1 "main" received signal SIGSEGV, Segmentation fault.
0x0000000180325278 in _gm_ () from /usr/bin/cygwin1.dll
(gdb) quit
function(pClass->class_member_function());
void function (MyResultClass x) { 
    std::cout<<"YES, IT WORKS"<<std::endl; 
}

class MyClass {
public: 
    MyResultClass class_member_function() {return MyResultClass{}; } 
    MyCompatibleClass class_member_function_compatible() {return MyCompatibleClass{}; } 
    MyIncompatibleClass class_member_function_incompatible() {return MyIncompatibleClass{}; } 
private: 
    MyResultClass private_class_member_function() {return MyResultClass{}; } 
};

int main() {
    MyClass *pClass=new MyClass();
    function(pClass->class_member_function());
    function(pClass->class_member_function_compatible());
    // function(pClass->class_member_function_incompatible());  // OUCH!!!
    // function(pClass->private_class_member_function());  //OUCH!!!
    return 0;
}
 function(pClass->Class_member_function());
             // ^^ dereference pClass
             //   ^^ access member Class_member_function
             //                        ^^ call it
       // pass result to function
struct P {
     int Class_member_function() { return 42; }
};
void function( int x) {}
function(42);