Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ equivalent of Python properties

Is there an equivalent of Python properties in C++? Or would it just be better to do this using getters and setters?

like image 455
Jim Jeffries Avatar asked Aug 18 '11 09:08

Jim Jeffries


People also ask

What is Property () in Python?

Python property() function returns the object of the property class and it is used to create property of a class. Syntax: property(fget, fset, fdel, doc) Parameters: fget() – used to get the value of attribute. fset() – used to set the value of attribute.

How do you access properties in Python?

getattr() – This function is used to access the attribute of object. hasattr() – This function is used to check if an attribute exist or not. setattr() – This function is used to set an attribute. If the attribute does not exist, then it would be created.

What are properties of a class in Python?

Class Properties In Python, a property in the class can be defined using the property() function. The property() method in Python provides an interface to instance attributes. It encapsulates instance attributes and provides a property, same as Java and C#.

What are properties and attributes in Python?

Attributes are described by data variables for example like name, age, height etc. Properties are special kind of attributes which have getter, setter and delete methods like __get__, __set__ and __delete__ methods.


2 Answers

In C++ you're either calling a member function, or you're accessing a data member. Python properties are essentially a way of doing the former using the syntax of the latter and there's no sensible way to do that in C++.

In theory you could hack together something with a macro, #define looks_like_data really_a_function() but it wouldn't be pretty. Or sensible. The only necessary reason to make a function look like data is to maintain compatibility with old calling code back from when it used to be data. But in C++ this won't give you binary compatibility, and it doesn't even really give you source compatibility given that the macro will break calling code that already uses the name looks_like_data for something else in another context. So there's not a lot of point.

Another thing you could do is to create an actual data member that acts as a proxy for the "logical" type of the data:

struct Proxy {
    Foo *foo;
    Proxy(Foo *foo) : foo(foo) { }
    operator int() const {
        // getter code goes here,
        // use (const Foo*)foo rather than foo
    }
    Proxy &operator=(int a) {
       // setter code goes here
    }
    // optionally also implement boilerplate +=, -=, etc.
};

struct Foo {
    // optionally 
    // friend class Proxy;
    Proxy looks_like_data;
    Foo() : looks_like_data(this) { }
};

This is almost, but not quite, sensible. Using an implicit conversion still breaks source compatibility, because there's a rule that there can only be one user-defined implicit conversion in a chain, so if a caller has written code back when looks_like_data really was an int, and their code implicitly converts that int to Bar, then once looks_like_data becomes a Proxy it will no longer implicitly convert to Bar and you've broken their code anyway.

So after all that, you're best using getter/setter functions if your class really needs something that looks like a read/write property.

like image 187
Steve Jessop Avatar answered Sep 21 '22 01:09

Steve Jessop


Yes, explicit getter and setters would be the closest construct in C++.

like image 39
Diego Sevilla Avatar answered Sep 24 '22 01:09

Diego Sevilla