The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Designing good C++ APIs

Here's an article you might find interesting. It's from the Qt Quarterly.

Simon Perreault Send private email
Thursday, July 14, 2005
That's very informative read.
JD Send private email
Thursday, July 14, 2005
BTW, I think lot of the concepts are applicable in general to API design rather than being applicable only for C++ API.
JD Send private email
Thursday, July 14, 2005
So you really prefer this:

    QSlider *slider = new QSlider(Qt::Vertical);
    slider->setRange(12, 18);

to this:
  QSlider *slider = new QSlider(12, 18, 3, 13, Qt::Vertical,
                                  0, "volume");

How about:

 new QSlider(/*range*/ 12, /*range*/ 18, /*pagestep*/ 3,
/*value*/ 13, Qt::Vertical, /*?*/ 0, /*object name*/ "volume");


int rangex= 12;
int rangey= 18;
int pagestep= 3;

new QSlider (rangex, rangey, pagestep, and so on);

In general I prefer an object to be full constructed without a lot of setting of attributes after constructed. It saves a lot of setters.
son of parnas
Thursday, July 14, 2005
It's lacking a little in the area of safety. In C++, it's vitally important to figure out who owns dynamic data that is passed/returned from functions. For example, if my function looks like this:

  Foo *getAFoo();

Am I as a caller responsible for deleting said Foo * when I'm done with it? Also, this is a memory leak waiting to happen.

It would have been nice if they'd discussed such issues.

P.S. The Herb Sutter approved fix for this would be to instead return:

  auto_ptr< Foo > getAFoo();

if the ownership is transferred to the caller, and straight Foo * if it isn't.
Chris Tavares Send private email
Thursday, July 14, 2005
If you want to learn about C++ memory management., Trolltech is the wrong place to go. They only use and support one style of memory management when using their classes, so they will only teach you that one style.

The basics are that if you add something to a parent class in QT, the parent will free the memory when it's destroyed.
Ben Atkin Send private email
Friday, July 15, 2005
How about this:

Slider *slider = new Slider(Slider::VERTICAL);

Monday, July 18, 2005
son of parnas: Yes, that's the whole point. The API is designed so that it leads naturally to writing readable code. If you use comments to make the code readable, that's you putting more energy into making your code readable while using an API that's not readable.

"": What's the benefit of using linked methods like that? More readable? Easier to type? I don't think so. It would certainly be confusing to see a lot of Thing& returned by functions which logically shouldn't return anything.
Simon Perreault Send private email
Tuesday, July 19, 2005
I think that in providing 1 example you get stuck on the specifics instead of generalising for any class.

In this case I'd prefere a mix that matched the logical model of the control, and minimal configuration to have complete initialisation. 

    QSlider *slider = new QSlider("volume", 12, 18, 3, Qt::Vertical);

I would still have it support
    slider->setRange(9, 21, 3);  /* to me page step is important here also, depending on the range the step could become incorrect  */

I you want to know what the magic numbers mean to the function, you look at the function header, if you want to know what they mean to the caller, well then the caller should have named them and probably made them constants.

Tuesday, July 19, 2005
Was anyone else impressed that Trolltech was humble enough to use their own API for examples of what not to do in an API?
Wednesday, July 20, 2005

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz