[英]How do I use static keyword inside class in C++ to emulate the behavior of @classmethod in Python?
我在某处@classmethod
Python中的@classmethod
类似于C ++中的静态成员函数。 但是C ++中的等效cls
参数是什么?我如何传递它?
下面是一个使用继承和@classmethod
的Python代码,
class Parent():
def __init__(self, name):
self._name = name
@classmethod
def produce(cls, name):
return cls(name)
def say_my_name(self):
print("I am parent", self._name)
class Child(Parent):
def say_my_name(self):
print("I am child", self._name)
p1 = Parent("One")
p1.say_my_name()
p2 = Parent.produce("Two")
p2.say_my_name()
p1 = Child("One")
p1.say_my_name()
p2 = Child.produce("Two")
p2.say_my_name()
现在我被困在我不完整的C ++代码中,如下所示
class Parent
{
protected:
std::string name;
public:
Parent(const std::string& name): name{name} {};
// Can I not use static in the next statement?
// Parent is already hard-coded, what's the cls in C++?
static Parent produce(const std::string& name) const
{
return Parent {name};
}
void say_my_name() const
{
std::cout << "I am parent " << name << "\n";
}
};
如何使用C ++模拟我的Python代码?
return Parent {name};
是正确的。 但是,静态成员函数不能是const
,因为没有调用它的对象。
在C ++中没有内置的方法来指定“当前类的类型”。 你只需要再写一次Parent
。 不幸的是,这意味着如果更改类的名称,则还必须更改类的实现中的所有相关事件。
为了模拟您在Pynthon代码中演示的用例,需要重复一些:
#include <iostream>
#include <string>
class Parent
{
protected:
std::string name;
public:
Parent() = default;
Parent(const std::string& name) : name{name} {};
using cls = Parent; // this isn't normally done, normally Parent is just repeated
// Can I not use static in the next statement?
// Parent is already hard-coded, what's the cls in C++?
//static Parent produce(const std::string& name) const
cls produce(const std::string& name) const // static would mean the function does not belong to any object, so it must be removed if we want to call it on a temporary const object
{
return cls{name};
}
void say_my_name() const
{
std::cout << "I am parent " << name << "\n";
}
};
class Child : public Parent {
public:
using cls = Child; // this isn't normally done, normally Child is just repeated
Child() = default;
Child(const std::string& name) : Parent{name} {};
void say_my_name() const
{
std::cout << "I am child " << name << "\n";
}
cls produce(const std::string& name) const // have to repeat produce() here so that it hides Parent::produce().
{
return cls{name};
}
};
int main()
{
auto p1 = Parent("One");
p1.say_my_name();
auto p2 = Parent().produce("Two");
p2.say_my_name();
auto c1 = Child("One");
c1.say_my_name();
auto c2 = Child().produce("Two");
c2.say_my_name();
}
这会产生:
I am parent One
I am parent Two
I am child One
I am child Two
这是一个使用static
的略微修改的版本:
#include <iostream>
#include <string>
class Parent
{
protected:
std::string name;
public:
Parent(const std::string& name) : name{name} {};
using cls = Parent; // this isn't normally done, normally Parent is just repeated
// Can I not use static in the next statement?
// Parent is already hard-coded, what's the cls in C++?
//static Parent produce(const std::string& name) const
static cls produce(const std::string& name) // here const would not make sense, this function will not be called on a particular instance of Parent
{
return cls{name};
}
void say_my_name() const
{
std::cout << "I am parent " << name << "\n";
}
};
class Child : public Parent {
public:
using cls = Child; // this isn't normally done, normally Child is just repeated
Child(const std::string& name) : Parent{name} {};
void say_my_name() const
{
std::cout << "I am child " << name << "\n";
}
static cls produce(const std::string& name) // have to repeat produce() here so that it hides Parent::produce().
{
return cls{name};
}
};
int main()
{
auto p1 = Parent("One");
p1.say_my_name();
auto p2 = Parent::produce("Two"); // No instance of Parent is used to create p2
p2.say_my_name();
auto c1 = Child("One");
c1.say_my_name();
auto c2 = Child::produce("Two");
c2.say_my_name();
}
但是,如果我们从一个干净的石板开始,并希望得到上面的结果。 我们可以写:
#include <iostream>
#include <string>
class Parent
{
protected:
std::string name;
public:
Parent(const std::string& name) : name{name} {};
void say_my_name() const
{
std::cout << "I am parent " << name << "\n";
}
};
class Child : public Parent {
public:
Child(const std::string& name) : Parent{name} {};
void say_my_name() const
{
std::cout << "I am child " << name << "\n";
}
};
template <typename T>
T produce(const std::string& name)
{
return{name};
}
int main()
{
Parent p1{"One"};
p1.say_my_name();
auto p2 = produce<Parent>("Two");
p2.say_my_name();
Child c1{"One"};
c1.say_my_name();
auto c2 = produce<Child>("Two");
c2.say_my_name();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.