21

I have the following code in C#:

public string Temp
        {
            get { return sTemp; }
            set { 
                sTemp = value;
                this.ComputeTemp();
            }
        }

Is it possible to convert this and use the get and set this way? I know that you cannot declare like so and I need the ":" to declare but when I try to do this:

public:
        std::string Temp
        {
        get { return sTemp; }
        set { 
                sTemp = value;
                this.ComputeTemp();
            }

The error I receive is on the first "{" stating expected a ';'. Any suggestions on how to fix it?

Undo
  • 25,519
  • 37
  • 106
  • 129
user2577497
  • 497
  • 9
  • 17
  • 14
    **Moderator Note:** This question has already run its course. If you want to comment on its veracity, take it to the [meta post](http://meta.stackexchange.com/questions/191089/why-do-we-let-hostile-users-dictate-the-perception-of-stack-overflow). Thanks. – Robert Harvey Jul 30 '13 at 20:01
  • 1
    Possible duplicate of [C#-like properties in native C++?](http://stackoverflow.com/questions/4225087/c-like-properties-in-native-c) – Peter Mortensen Jul 31 '13 at 23:19

3 Answers3

38

Are you using C++/CLI? If so this is the property syntax

public:
  property std::string Temp { 
    std::string get() { return sTemp; }
    void set(std::string value) { sTemp = value; this->ComputeTemp(); } 
  }

If you are trying to use normal C++ then you are out of luck. There is no equivalent feature for normal C++ code. You will need to resort to getter and setter methods

public:
  std::string GetTemp() const { return sTemp; } 
  void SetTemp(const std::string& value) { 
    sTemp = value;
    this->ComputeTemp();
  }
Bart
  • 19,692
  • 7
  • 68
  • 77
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 3
    In the latter case, the standard naming convention seems to be `T temp()` for the getter and `void temp(T value)` for the setter. – CodesInChaos Aug 02 '13 at 11:27
  • @CodesInChaos I've definitely seen both ways (Get / Set prefix and no prefix). My personal preference is to have the Get / Set prefix, possibly a hold over from my early Java days – JaredPar Aug 02 '13 at 15:14
11

To copy paste one of my answers from a similar question:

WARNING: This is a tongue-in-cheek response and is terrible!!!

Yes, it's sort of possible :)

template<typename T>
class Property
{
private:
    T& _value;

public:
    Property(T& value) : _value(value)
    {
    }   // eo ctor

    Property<T>& operator = (const T& val)
    {
        _value = val;
        return(*this);
    };  // eo -

    operator const T&() const
    {
        return(_value);
    };  // eo ()
};

Then declare your class, declaring properties for your members:

class Test
{
private:
    std::string m_Test;

public:
    Test() : text(m_Test)
    {
    };

    Property<std::string> text;
};

And call C# style!

Test a;
a.text = "blah";

std::string content = a.text;
Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
  • Note that Properties in this manner make the class a little larger than they'd otherwise be – Mooing Duck Jul 30 '13 at 19:52
  • @MooingDuck, correct - but I'd also advise doing it in the first place, hence the disclaimer at the top - point being - it *can* be done... just.. yeah... ;) – Moo-Juice Jul 30 '13 at 19:55
  • Copy construction of `Test` and `Test::operator=` are disastrous. You need to either handle it properly, or block it. – Yakk - Adam Nevraumont Jul 30 '13 at 21:04
  • 2
    Oh, and you can get rid of the overhead, *and* have a working `operator=`, by simply giving up on `.` syntax. Use `static TestProperty text;` to introduce a name into the global scope with suitable overrides to `operator^` and you can get `a^text = "blah"` to work to work, with zero run time overhead. To add to the C#ness, `Test* a; a^text` and `Test a; a^text` can both do the same thing: why store the `Test` object when the statement *has it right there*, all we need to do is some expression template mojo to grab it and use it! – Yakk - Adam Nevraumont Jul 30 '13 at 21:20
3

In Visual C++ you can use __declspec(property), like this:

public:
    __declspec(property(get=get_Temp, put=set_Temp)) std::string Temp;

    const std::string& get_Temp { return sTemp; }
    void set_Temp(std::string value) { 
            sTemp = std::move(value);
            this->ComputeTemp();
    }
Abyx
  • 12,345
  • 5
  • 44
  • 76
  • However, it's better to just use `get_Temp/set_Temp` directly, without the property `Temp`, because it's way easier to grep places where Temp is accessed/modified. – Abyx Jul 31 '13 at 05:05