views:

802

answers:

6

Having read this thread:

http://stackoverflow.com/questions/3017/how-to-generate-getters-and-setters-in-visual-studio

and tried (somewhat) the techniques described, I have failed miserably to graduate beyond the longhand way of writing Getters and Setters.

While I recognize the conceptual advantage of encapsulation (private members of a class in this case) Writing 25 getters and setters is a waste of space and my time.

Why 25? Well apart form the exageration factor (approx 2.5) I just don't know at what point I will need access to that one variable in the future. I guess I could write a function that returns all of them and fish out the one I need, but if I add more members (often do) then the function must be changed throughout the code.

I like the form suggested here

http://geekswithblogs.net/wojan/archive/2007/12/12/117629.aspx

of

string sName { get; set; }

But it wont compile in C++. Is this just for .NOT and C#

http://www.c-sharpcorner.com/UploadFile/john%5Fcharles/WhatnewinVisualStudioNET200802012008121831PM/WhatnewinVisualStudioNET2008.aspx

Is there some tidy way to simulate this in C++?

+1  A: 

Automatically implemented properties are indeed a feature of C#. As far as I'm aware, they're not available in C++. I believe they're coming in VB 10, but I don't know if they'll be introduced into C++/CLI.

There are lots of language features which are part of C# but not C++ (and vice versa, of course). You shouldn't expect to just be able to use the syntax of one language in another.

I would caution against writing properties "just in case" though. If you're going to basically give complete access to everything in your type via a property, even though you don't know whether you'll need it, that hasn't encapsulated much. Adding read-only properties is somewhat better, but it's nicer to avoid tying your higher-level abstraction to the variables you happen to be using now. If these properties are part of the intrinsic nature of the type (i.e. you'd expect any implementation of the same concept to expose the same properties) then that's a slightly different matter.

EDIT: As you don't want to use managed code, you won't even be using C++/CLI, which makes it even less likely that you'll be able to use C# features.

Jon Skeet
expect no. hope perhaps. workaround yes
Mike Trader
I think it's better to learn the language you're *actually* using thoroughly, instead of even *hoping* to be able to just use syntax from other languages.
Jon Skeet
You got no argument about learning a language, but isn't the whole point of refactoring to reduce bloat and make code more readable? Why do I need to wade through 25 trivial GET and SET's before I arrive at the first thing of real interest to anyone reading the code? As you may have gathered, I like tight "to the point" code that is readable and easy on the eye. It's just so much more productive to work with.
Mike Trader
@Mike: In that case you should use a language which is more productive to work with than C++...
Jon Skeet
A: 

Properties originated (I believe) in Delphi and migrated to other languages, most notably C#. There's no built-in support for them in C++ (though I could be wrong in the case of C++.NET - haven't checked lately).

I found this article on simulating properties, which looks complex but might solve your problem. Also, consider using C# if it suits your application -ie, you're not writing a device driver. It's got an amazing object model and lots of other benefits. It doesn't replace C++ in every aspect, but is great for most applications. As a very smart friend of mine said, use the highest-level language that makes sense for your project.

David Lively
'consider using C#' Managed code is not for me. Thanks anyway.
Mike Trader
Thank you for the article link, but that is a lot of trouble for a relatively simple problem. I'm looking to reduce project code if possible
Mike Trader
+1  A: 

Refactor! by DevExpress has some pretty nice features for C++, one of which is encapsulating fields like C#.

The plugin uses DirectX overlays in the text editor to offer a list of available actions for whatever you've typed. so if you type:

float id;

the plugin will animate an indicator to show options such as Encapsulate Field, which will add:

property float Id
{
    void set(float value)
    {
        this->_id = value;
    }
    float get()
    {
        return this->_id;
    }
};

If installing a plugin really isn't your thing, consider using macros.

Personally, I prefer using macros. Once you get the hang of them, they're really easy. I've used both, but we're stuck in Visual Studio 2003 (C#) until December, and DevExpress plugins don't work.

The way I usually use macros is to start at the beginning of a line, hit CTRL+SHIFT+R to begin recording. Then, type, copy, and paste the steps I'd like to recreate. When finished, hit CTRL+SHIFT+R to stop recording. Then, CTRL+SHIFT+P will playback the last recording. You can also go into Macro Explorer and save/edit your macros. Then, you can just double click macros to run them.

Jim Schubert
Thank you for the first real answer! Could you elaborate a little pls. Have you used both? Which do you prefer and why? How are the fields encapsulated (code example would be great)
Mike Trader
Thanks, Mike. I edited my answer a little to elaborate. I used Refactor! for my C++ class in school. It was very useful. I like macros because I can do exactly what I want very quickly.
Jim Schubert
+4  A: 

Thanks @Dan for pointing out this trick in Microsoft Compiler (non-portable)

Here is the way:

struct person
{
    std::string m_name;
    void setName(const std::string& p_name)
    {
     m_name = p_name;
    }
    const std::string& getName() const
    {
     return m_name;
    }
    // Here is the name of the property and the get, set(put) functions
    __declspec(property(get = getName, put = setName)) std::string name;
};
int main()
{
    person p;

    p.name = "Hello World!"; // setName(...)
    std::cout << p.name;     // getName(...)
}

After creating your member variables plus the getters and setters of these member variables, you create a property for each getter/setter pair. You can call it whatever you want, because you have to specify the getter and setter for this property.


Just for fun :)

#define property(Type, Variable) private: Type Variable; \
      public: const Type##& get##Variable() const { return Variable; }; \
      void set##Variable(const Type& Variable##_) { Variable = Variable##_;}


 struct Test
 {
     property(int, x); property(int, y);
     property(std::string, text);
 };

int main()
{
    Test t;

    t.setx(10);
    t.sety(10);
    t.settext("Hello World at: ");
    std::cout << t.gettext() << " " << t.getx() << ", " << t.gety();
}
AraK
Now that is what i'm talking about. Brilliant. Thank you.
Mike Trader
You could even combine this with __declspec (Microsoft-specific) and get "real" properties: t.x, t.y and t.text.
Dan
Dan could you elaborate for VS2008 please.
Mike Trader
@Mike I added an example of `declspec(property(...))`.
AraK
+1  A: 

C++/CLI supports automatically implemented properties - it calls them "Trivial Properties" 1

Paul Baker
Do these still exist in .NET 3.5? I tried them before, but they didn't work (compiler complained about missing get/set or something similar)
Jim Schubert
Since this is "for .NOT [sic] and C#", I would think C++/CLI would be close enough to C++ to be acceptable.
Dan
+1  A: 

Why 25? Well apart form the exageration factor (approx 2.5) I just don't know at what point I will need access to that one variable in the future.

You realize this means you really haven't thought your design through much. Instead of finding ways to add properties to C++ (it doesn't need them). Should I call them "properduhs" to explain the extent of my dislike for them?

You should be spending time creating a design for your class so that you know what parts should be visible to the class's user (and therefore need some form of getter), which parts might need to updated (and therefore some form of action method would be needed) and which are truly internal. Notice I said nothing about setters. Setters are lazy constructs that allow you to not plan your class. Methods should do things. By do things I mean actual work should take place not just some number is updated somewhere. If something is just a number, make it public. If there might be side effects, make a method that gives you a clue as to what is being done (both the value changing and the side effect as well). If you don't know if there might be a side effect, go back to the design table and find out.

I realize this goes against the "rule of thumb" that data should be encapsulated privately with getters and setters so that if the design of the class changes, users of the class are immune to the changes. Well, to heck with that. Get it right the first time and spend less time fussing about it later. My approach is give the class user access to NOTHING but a small set of methods and then if you find it important to allow them access to some private value later you can add a getter() later. When I said "just make it public" it should be understood that means "after exhaustive consideration I know it is absolutely safe to make this public because I have fully and completely designed my class with all use cases in mind."

Okay, now go ahead an ding this answer because it answers the heart of the question rather than the letter of the question. I expect it.

jmucchiello
Oh don't be afraid of the dings... this is EXACTLY the core issue. Please help me frame a question I can ask that will a) not start a major war and b) solicit a fruitful debate on this issue. I have the code example ready to go!
Mike Trader
You've already received advice for writing a question in a more fruitful way: don't refer to platforms/languages/etc in a distractingly childish way. You're ignoring that advice though...
Jon Skeet
The problem is stackoverflow is not a place for debate. It is a places for answers to questions. What are you trying to ask? Do you want help designing your class? Post a question like "how can I improve this?" Of course, stackoverflow is also not a place for design critiques. It is supposed to be a place for specific answers to specific questions but questions that someone else might ask as well. Still, the best way not to start a war is not to slap someone in the face saying .NOT to them.
jmucchiello
Shelving a popular development language like VB (that many have a large $$ investment in) REQUIRING a costly migration to something new, is what many have called a big slap in the face. Moving on, every thread on stack overflow is by definition a debate. Joe asserts x, Bill asserts y. You raise a controversial issue in your answer "Get it right the first time..." (which flies in the face of Agile concepts) let alone making data public. It sees like this IS the place to explore those ideas, hence the suggestion to do so in another thread. The question in this thread has been answered.
Mike Trader
Yes, I do. But that doesn't mean it is stackoverflow is "about". The answers to a question should be a discussion, not a debate. Regardless, while the short version of my answer is indeed "get it right the first time", in the long view all I'm saying is "don't just sit down and code." The old carpenters' saying, "measure twice, cut once" is apropos. The more time you can spend when the code size if zero the less time you need to spend refactoring that code later.
jmucchiello
Mike Trader