Rad*_*nsa 89 c# c++ class c++11
在C#中,对于具有getter和setter的字段,有一个很好的语法糖.而且,我喜欢允许我编写的自动实现的属性
public Foo foo { get; private set; }
Run Code Online (Sandbox Code Playgroud)
在C++中我必须写
private:
Foo foo;
public:
Foo getFoo() { return foo; }
Run Code Online (Sandbox Code Playgroud)
在C++ 11中是否有一些这样的概念允许我对此有一些语法糖?
psx*_*psx 77
在C++中,您可以编写自己的功能.以下是使用未命名类的属性的示例实现.维基文章
struct Foo
{
class {
int value;
public:
int & operator = (const int &i) { return value = i; }
operator int () const { return value; }
} alpha;
class {
float value;
public:
float & operator = (const float &f) { return value = f; }
operator float () const { return value; }
} bravo;
};
Run Code Online (Sandbox Code Playgroud)
您可以编写自己的getter和setter,如果您想要持有者类成员访问,您可以扩展此示例代码.
Mic*_*vin 46
C++没有内置的,你可以定义一个模板来模仿属性功能:
template <typename T>
class Property {
public:
virtual ~Property() {} //C++11: use override and =default;
virtual T& operator= (const T& f) { return value = f; }
virtual const T& operator() () const { return value; }
virtual explicit operator const T& () const { return value; }
virtual T* operator->() { return &value; }
protected:
T value;
};
Run Code Online (Sandbox Code Playgroud)
要定义属性:
Property<float> x;
Run Code Online (Sandbox Code Playgroud)
要实现自定义getter/setter,只需继承:
class : public Property<float> {
virtual float & operator = (const float &f) { /*custom code*/ return value = f; }
virtual operator float const & () const { /*custom code*/ return value; }
} y;
Run Code Online (Sandbox Code Playgroud)
要定义只读属性:
template <typename T>
class ReadOnlyProperty {
public:
virtual ~ReadOnlyProperty() {}
virtual operator T const & () const { return value; }
protected:
T value;
};
Run Code Online (Sandbox Code Playgroud)
并在课堂Owner
上使用它:
class Owner {
public:
class : public ReadOnlyProperty<float> { friend class Owner; } x;
Owner() { x.value = 8; }
};
Run Code Online (Sandbox Code Playgroud)
您可以在宏中定义上面的一些内容,使其更简洁.
Com*_*hip 22
C++语言中没有任何内容适用于所有平台和编译器.
但是,如果您愿意打破跨平台兼容性并提交到特定的编译器,您可以使用这种语法,例如在Microsoft Visual C++中,您可以
// declspec_property.cpp
struct S {
int i;
void putprop(int j) {
i = j;
}
int getprop() {
return i;
}
__declspec(property(get = getprop, put = putprop)) int the_prop;
};
int main() {
S s;
s.the_prop = 5;
return s.the_prop;
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ker 18
可以通过具有专用类型的成员和重写模拟getter和setter在一定程度上operator(type)
和operator=
它.这是一个好主意是另一个问题,我要去+1
Kerrek SB的回答表达我的意见:)
the*_*int 17
也许看看我在过去几个小时内组建的属性类:https://codereview.stackexchange.com/questions/7786/c11-feedback-on-my-approach-to-c-like-class-properties
它允许您使属性如下所示:
CTestClass myClass = CTestClass();
myClass.AspectRatio = 1.4;
myClass.Left = 20;
myClass.Right = 80;
myClass.AspectRatio = myClass.AspectRatio * (myClass.Right - myClass.Left);
Run Code Online (Sandbox Code Playgroud)
Nic*_*man 17
使用C++ 11,您可以定义一个Property类模板并使用它如下:
class Test{
public:
Property<int, Test> Number{this,&Test::setNumber,&Test::getNumber};
private:
int itsNumber;
void setNumber(int theNumber)
{ itsNumber = theNumber; }
int getNumber() const
{ return itsNumber; }
};
Run Code Online (Sandbox Code Playgroud)
这里是Property类模板.
template<typename T, typename C>
class Property{
public:
using SetterType = void (C::*)(T);
using GetterType = T (C::*)() const;
Property(C* theObject, SetterType theSetter, GetterType theGetter)
:itsObject(theObject),
itsSetter(theSetter),
itsGetter(theGetter)
{ }
operator T() const
{ return (itsObject->*itsGetter)(); }
C& operator = (T theValue) {
(itsObject->*itsSetter)(theValue);
return *itsObject;
}
private:
C* const itsObject;
SetterType const itsSetter;
GetterType const itsGetter;
};
Run Code Online (Sandbox Code Playgroud)
Tra*_*lio 15
正如许多其他人已经说过的那样,语言中没有内置的支持.但是,如果您的目标是Microsoft C++编译器,则可以利用此处介绍的属性的Microsoft特定扩展.
这是链接页面的示例:
// declspec_property.cpp
struct S {
int i;
void putprop(int j) {
i = j;
}
int getprop() {
return i;
}
__declspec(property(get = getprop, put = putprop)) int the_prop;
};
int main() {
S s;
s.the_prop = 5;
return s.the_prop;
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*son 12
不,C++没有属性的概念.虽然定义和调用getThis()或setThat(value)可能很尴尬,但是您正在向消费者声明某些功能可能会发生的方法.另一方面,访问C++中的字段告诉消费者不会发生其他或意外的功能.属性会使这一点变得不那么明显,因为乍一看属性访问似乎像字段一样反应,但实际上反应就像一个方法.
另外,我正在尝试创建客户会员系统的.NET应用程序(一个非常着名的CMS)中工作.由于他们使用属性作为用户对象的方式,我没有预料到会触发操作,导致我的实现以奇怪的方式执行,包括无限递归.这是因为他们的用户对象在尝试访问像StreetAddress这样的简单事物时调用了数据访问层或某个全局缓存系统.他们的整个系统建立在我称之为滥用财产的基础之上.如果他们使用方法而不是属性,我想我会更快地弄清楚出了什么问题.如果他们使用了字段(或至少使他们的属性更像字段),我认为系统将更容易扩展和维护.
[编辑]改变了我的想法.我有一个糟糕的一天,并有点咆哮.这种清理应该更专业.
Kai*_*udi 11
基于/sf/answers/1617667341/,这是一个带有公共getter和私有setter的版本:
struct Foo
{
class
{
int value;
int& operator= (const int& i) { return value = i; }
friend struct Foo;
public:
operator int() const { return value; }
} alpha;
};
Run Code Online (Sandbox Code Playgroud)
这不完全是一个属性,但它以简单的方式实现您想要的功能:
class Foo {
int x;
public:
const int& X;
Foo() : X(x) {
...
}
};
Run Code Online (Sandbox Code Playgroud)
这里大 X 的行为类似于public int X { get; private set; }
C# 语法。如果您想要成熟的属性,我在这里第一次尝试实现它们。
您可能知道,但我会简单地执行以下操作:
class Person {
public:
std::string name() {
return _name;
}
void name(std::string value) {
_name = value;
}
private:
std::string _name;
};
Run Code Online (Sandbox Code Playgroud)
这种方法很简单,没有巧妙的技巧,它完成了工作!
但问题是,有些人不喜欢用私人字段加上下划线,所以他们不能真正使用这种方法,但幸运的是,对于这些人来说,这真的很简单.:)
get和set前缀不会增加你的API的清晰度,但会使它们更加冗长,我不认为它们添加有用信息的原因是因为当有人需要使用API时,如果API有意义,她可能会意识到它是什么没有前缀.
还有一件事,很容易理解这些属性是因为name
它不是动词.
最糟糕的情况是,如果API是一致的,并且该人没有意识到这name()
是一个访问器并且name(value)
是一个变异器,那么她只需要在文档中查找一次以理解模式.
尽管我喜欢C#但我认为C++根本不需要属性!
归档时间: |
|
查看次数: |
60119 次 |
最近记录: |