После небольшого количества экспериментов я обнаружил кое-что любопытное в Python (возможно, очевидное для экспертов, простите меня в этом случае).
То есть метод класса Python может быть вызван с двумя различными синтаксисами, в отличие от C ++. Я приведу два минимальных рабочих примера с простым классом, который просто содержит целочисленный атрибут и может добавить к нему другое целое число. Сначала 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 ++?
Классы Python являются объектами времени выполнения. Каждый предмет несет с собой __class__
указатель.
Когда вы делаете obj.foo(x)
сначала это выглядит локально для foo
Способ; если он не может найти его, он вызывает obj.__class__.foo(obj, x)
,
В C ++ классы не являются объектами времени выполнения. У объекта с виртуальными методами или наследованием есть vtable, но vtable — это не класс, а скорее способ достичь минимума & эффективный тип и диспетчеризация информации для методов.
Теперь вы все равно можете вызывать метод C ++ таким же образом, как и метод python:
template<class T>
T& as_lvalue(T&&t){return t;}
std::ref( as_lvalue(&MyClass::add) )( anObject, 6 );
это использует концепцию INVOKE (пост C ++ 17 Вы можете использовать его напрямую с помощью std invoke) и указателя на функцию-член.
Это библиотечное решение. Здесь нет MyClass
объект в исполняемом файле во время выполнения.
Других решений пока нет …