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