扩展 C++类不修改头

发布于 2025-01-05 11:12:06 字数 355 浏览 0 评论 0原文

在 C++ 或任何其他编译语言中,是否可以在不修改标头的情况下向类添加功能?

在 JavaScript 中,我可以在创建对象后向对象添加函数。在 C++ 中,有什么可能是远程的吗?

一个使用示例是我向用户提供一些 routine.o 文件,并让他们扩展它,使用类似的内容。

void routine::NeverBeforeDeclaredFunction() { ... }

不允许使用此确切的示例,但有什么类似的吗?我考虑过让此类拥有一个函数指针数组,并让用户用自己的函数填充该数组。但这并没有提供任何优势,例如访问私有变量或访问this

Is it possible, in C++ or any other compiled language, to add functionality to a class without modifying the header?

In JavaScript I can add a function to an object after the object is created. Is anything even remote possible in C++?

A use example would be for me to provide a user with some routine.o file, and have them extend it, with something like

void routine::NeverBeforeDeclaredFunction() { ... }

This exact example isn't allowed, but is anything similar? I've thought about letting this class have an array of function pointers, and have a user populate that array with their own function. But this doesn't provide any advantage, such as access to private variables, or access to this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

不甘平庸 2025-01-12 11:12:07

在编译语言中,Objective C 更具动态性,但其功能与 Javascript(一种基于原型继承的语言)不同。

在 C++ 中,您可以做的是提供一个采用 std::string 的虚方法,并返回一个函数指针,该函数指针采用您的类的实例作为其第一个参数,以实现穷人版本的动态派遣。在此实例中唯一需要共享的是函数指针的类型。

Of the compiled languages Objective C is great deal more dynamic, but its facilities are not the same as in Javascript, a language with prototype-based inheritance.

What you can do in C++ is to provide a virtual method taking a std::string, and returning a function pointer that takes an instance of your class as its first argument, for a poor man's version of dynamic dispatch. The only thing that would need to be shared in this instance is the type of the function pointer.

£噩梦荏苒 2025-01-12 11:12:07

至少对于 C++ 来说,答案是否定的。标头的想法是完全捕获所声明的对象/函数的整个接口。即使您可以这样做,也可能不是一个好的做法。

成员函数(不是虚拟的)都有一个隐式的“this”参数,允许它们访问其父对象的成员,也许您可​​以使用具有显式“this”参数的函数指针。至于访问私有成员,您可以尝试将函数声明为友元(不幸的是需要更改标头)。

The answer, at least for c++, would be no. The idea of a header is to fully capture the entire interface of the objects/functions being declared. Even if you could do so, it probably wouldn't be good practice.

Member functions (that aren't virtual) all have an implicit "this" parameter which allows them to access their parent object's members, perhaps you could use function pointers which have an explicit "this" parameter. As for access to private members, you can try declaring the functions a friend (unfortunately requires changing the header).

¢好甜 2025-01-12 11:12:07

问题不是在“编译”与“未编译”语言之间,而是在“严格类型”和“弱类型”语言之间。

对于严格类型的面向对象语言,只有类的扩展才能引入新方法。这就是“对象”的意义所在。但扩展对象还要求您能够控制对象的创建。

然而,对这样的东西的需求时不时就会出现——每种语言都会提出一些东西,允许一些看起来像“扩展”的东西(避免“扩展”,因为这是在这种情况下的面向对象术语)现有的东西。

例如,C++ 使用流的方法重载,以便可以使其工作:

cout << var_of_some_non_standard_type;

在 C# 中,您有扩展方法 - 在您自己的代码中,您可以假装一个类具有更多方法。编译器将它们映射到静态方法。

在 Java 中,您还可以通过在您自己的代码中使用函数的静态导入来进行假装。

The question is not between "compiled" vs "not compiled" languages but between "strictly typed" and "weakly typed" languages.

For strictly typed object oriented languages only extension of classes can bring in new methods. That's quite the point of "objects". But extending object also requires, that you have control over the creation of the objects.

However, the need for something like this comes up now and then - and each language comes up with something that allows something which just looks like "expanding" (avoiding "extending" as this is the OO term in this context) existing stuff.

C++ for example uses method overloading for streams, so that this can be made to work:

cout << var_of_some_non_standard_type;

In C# you have Extension Methods - in your own code you can pretend, that a class has some more method. The compiler maps them to static methods.

In Java you can also pretend as little bit by using static imports for functions in your own code.

银河中√捞星星 2025-01-12 11:12:07

这取决于您所说的扩展功能的含义。

通常,扩展功能意味着扩展类。因此,是的,您可以从该类派生并添加更多功能,同时仍保留基类的类型。继承是一种is-a关系。

如果您指的是向现有类添加功能而不扩展它或修改标头,那么不,这是不可能的。如果你问我,这是一件好事。

It depends on what you mean by extending functionality.

Usually, extending functionality translates to extending the class. So, yes, you can derive from the class and add more functionality, while still retaining the type of your base class. Inheritance is a is-a relationship.

If you're referring to adding functionality to the already existing class without extending it or modifying the header, then no, that is impossible. If you ask me, this is a good thing.

筱武穆 2025-01-12 11:12:07

我们可以通过运算符重载向现有类添加功能。

class details 
{
    public:
    std::string name;
};

bool operator==(const details& lhs,const details& rhs)
{
    return(lhs.name==rhs.name);
}

void operator<<(details& lhs,const std::string& json)
{   
    Poco::JSON::Parser parser;
    Poco::Dynamic::Var result = parser.parse(json);
    Poco::JSON::Object::Ptr pObject = result.extract<Poco::JSON::Object::Ptr>();
    lhs.name = pObject->getValue<std::string>("name");    
}

int main(int, char **)
{
    std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }";
    details a,b;
    a==b;//though not a member would behave like one
    a<<json;//i m able to parse json using operator overloading
    std::cout<<a.name<<std::endl;
}

您可以使用其他运算符来添加功能。

We can add functionality to an existing class by means of operator overloading.

class details 
{
    public:
    std::string name;
};

bool operator==(const details& lhs,const details& rhs)
{
    return(lhs.name==rhs.name);
}

void operator<<(details& lhs,const std::string& json)
{   
    Poco::JSON::Parser parser;
    Poco::Dynamic::Var result = parser.parse(json);
    Poco::JSON::Object::Ptr pObject = result.extract<Poco::JSON::Object::Ptr>();
    lhs.name = pObject->getValue<std::string>("name");    
}

int main(int, char **)
{
    std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ] }";
    details a,b;
    a==b;//though not a member would behave like one
    a<<json;//i m able to parse json using operator overloading
    std::cout<<a.name<<std::endl;
}

You can use other operators to add functionality.

但可醉心 2025-01-12 11:12:06

用 C++ 可能吗

不,在 C++ 中,您不能在运行时或编译时执行此操作。至少便携性不那么让人头疼。您可以创建一个子类,但它不是“同一个类”。如果该类是模板类,您可以提供自己的专业化(但它是不同的类型)。

C++/CX(C++ 的 Microsoft 语言扩展)允许使用部分类。如果您不关心可移植性,这可能是您问题的解决方案。请注意,它是在编译时完成的。

或任何其他编译语言,在不修改标头的情况下向类添加功能?

Objective-C 通过类别(编译时)和 Objective-C 运行时(运行时)允许这样做。

Is it possible, in C++

No, you cannot do that at runtime nor at compile time in C++. At least not portably without many headaches. You can create a subclass, but then it's not "the same class". If the class is a template class, you could provide your own specializations (but then it's a different type).

C++/CX (a Microsoft language extension to C++) allows for partial classes. This might be a solution to your problem, if you don't care about portability. Note that it is done at compile-time.

or any other compiled language, to add functionality to a class without modifying the header?

Objective-C allows this through categories (compile time) and through the Objective-C runtime (runtime).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文