【问题标题】:Why do not C++ object methods expect a self argument unlike python? [closed]为什么 C++ 对象方法不像 python 那样期望 self 参数? [关闭]
【发布时间】:2018-11-26 02:41:58
【问题描述】:

经过一些实验后,我在 Python 中发现了一些奇怪的东西(对于专家来说可能很明显,在这种情况下请原谅我)。 也就是说,与 C++ 不同,可以使用两种不同的语法调用 python 类方法。我将给出两个最小的工作示例,其中包含一个简单的类,它只包含一个整数属性,并且可以向它添加另一个整数。首先是 C++。

#include <iostream>
using namespace std;
class MyClass
{
    int value;
    public:
    MyClass(int arg){value=arg;}
    int add(int arg){return arg+value;}
};

int main()
{
    MyClass anObject(4);
    cout<<"The addition gives "<<anObject.add(6)<<endl;//Outputs 10

    //cout<<"The alternative way to call the method gives "<<MyClass.add(anObject, 6)<<endl;  //Does not work

   //cout<<"Another alternative way to call the method gives "<<MyClass::add(anObject, 6)<<endl;  //Does not work either

   return EXIT_SUCCESS;
}

还有蟒蛇。

class MyClass(object):
    def __init__(self, arg=3):self.value=arg
    def add(self, arg):return arg+self.value
anObject=MyClass(4)
print(anObject.add(6)) #The C++ way, Outputs 10
print(MyClass.add(anObject, 6))  #Outputs 10

显然,这不是我要解决的问题,但这个问题的目的是讨论为什么选项 2 是 python 的一个特性,而它不是 C++ 的一个特性?它是源于语言的一些更深层次的设计理念,还是与语言的编译与解释性质有关?相关,为什么self 在 python 中作为虚拟参数出现,但在 C++ 中却没有?

【问题讨论】:

  • 请随意将value 称为this-&gt;value。你会惊讶地发现每个类方法都有一个叫做this的东西,它是一个指针,在逻辑上等价于python的self
  • x.add(6)不是比WhatEverXIs.add(x, 6)简单吗?
  • add(anObject, 6) -- 这看起来与试图模拟面向对象的C 语法没有什么不同。这是倒退了一步。
  • 看看std::bind (https://en.cppreference.com/w/cpp/utility/functional/bind)。它可能提供类似的东西......但更复杂
  • C++ 成员函数 are 以对象 (this) 作为第一个参数调用 - 他们怎么知道要操作哪个对象?只是编译器在幕后为你做这件事。

标签: c++ python-3.x oop python-object


【解决方案1】:

Python 类是运行时对象。每个对象都带有一个__class__ 指针。

当您执行obj.foo(x) 时,它首先在本地查找foo 方法;如果找不到,它会调用obj.__class__.foo(obj, x)

在 C++ 中,类不是运行时对象。具有虚拟方法或继承的对象有一个 vtable,但 vtable 不是类,而是一种获取最小且高效的类型和方法调度信息的方法。

现在您仍然可以像 python 那样调用 C++ 方法:

template<class T>
T& as_lvalue(T&&t){return t;}

std::ref( as_lvalue(&MyClass::add) )( anObject, 6 );

这使用了 INVOKE 概念(发布,您可以直接将其与 std 调用一起使用)和成员函数指针。

这是一个图书馆解决方案。运行时可执行文件中没有MyClass 对象。

【讨论】:

  • 当我尝试 std::ref 时,我得到use of deleted function ‘void std::ref(const _Tp&amp;&amp;) [with _Tp = int (MyClass::*)(int)]’
  • 但是,就像你说的,发布 c++17 你可以这样做:std::invoke(&amp;MyClass::add, anObject, 6)
  • @jerry 已修复。哎呀。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 2011-02-06
相关资源
最近更新 更多