[Newbie] How to use a class in C++

P

pozz

I have a medium experience in C and now I'm learning C++. I have some
difficulties to think by and use classes, so with object oriented
programming.

In my application I have a configuration file that stores some
settings in non-volatile way. Several parts, modules and classes could
access the configuration file both for reading and writing settings.

In C I can create settings.h with the interface:
---
int settings_read(const char *name, char *value, size_t valuesize);
int settings_save(const char *name, const char *value);
---
Every other module that wants to use the settings facilities will
include "settings.h" and user settings_read() and settings_write().
The implementation and any additional data (such as the filename) are
hidden in settings.c.

In C++ I was trying to create a class in settings.h, but I'm not sure
if I should add private data there:
---
class Settings {
const char filename[] = "settings.ini";
public:
void Settings(void);
virtual ~Settings(void);
int settings_read(const string name, string value);
int settings_save(const string name, const string value);
};
---
Why the user should know about private data, like filename? I'm
tempted to avoid adding private data/functions in the class
declaration in settings.h, but in settings.c as typical static names
(like in C). I don't know if this is a good approach, because I have
seen many C++ source files with private names in include file.
 
A

Alf P. Steinbach

I have a medium experience in C and now I'm learning C++. I have some
difficulties to think by and use classes, so with object oriented
programming.

In my application I have a configuration file that stores some
settings in non-volatile way. Several parts, modules and classes could
access the configuration file both for reading and writing settings.

In C I can create settings.h with the interface:
---
int settings_read(const char *name, char *value, size_t valuesize);
int settings_save(const char *name, const char *value);
---
Every other module that wants to use the settings facilities will
include "settings.h" and user settings_read() and settings_write().
The implementation and any additional data (such as the filename) are
hidden in settings.c.

In C++ I was trying to create a class in settings.h, but I'm not sure
if I should add private data there:

Use a std:.string.

Don'e make it `const`.

public:
void Settings(void);
virtual ~Settings(void);

`void` to indicate "no arguments" is a C-ism. It's necessary in C. It's
not necessary in C++.

int settings_read(const string name, string value);

Better pass by reference, like

int read( string const& name, string const& value );


int settings_save(const string name, const string value);
};
---
Why the user should know about private data, like filename? I'm
tempted to avoid adding private data/functions in the class
declaration in settings.h, but in settings.c as typical static names
(like in C). I don't know if this is a good approach, because I have
seen many C++ source files with private names in include file.

The difference with a class is that the using code creates an instance
of it.

Each instance can have its own filename.


Cheers & hth.,

- Alf
 
J

Juha Nieminen

pozz said:
In C I can create settings.h with the interface:

If that design suffices for your purposes, then I don't see why you
couldn't use that exact same code in your C++ program as well. (Although
if this is a generic library to be used in more than one project, you
might want to consider putting those functions inside a namespace with
some appropriate name. Not that it's mandatory, but it lessens the chances
of name collisions in large projects.)

One of the practical advantages of classes is that, like structs, you
can instantiate more than one at a time, and each instance will be
independent of each other, and they can co-exist at the same time.
(The advantage over C structs is that you have more control over access
rights, it's modular because you can use member functions, and you have
RAII, which is very useful in many cases. This not even going into
inheritance and dynamic binding.)

However, just because there are classes doesn't necessarily mean that
everything *must* be a class. If someting can be implemented as a
function, and there's no need for anything else, then why not.
 
G

Goran

I have a medium experience in C and now I'm learning C++. I have some
difficulties to think by and use classes, so with object oriented
programming.

In my application I have a configuration file that stores some
settings in non-volatile way. Several parts, modules and classes could
access the configuration file both for reading and writing settings.

In C I can create settings.h with the interface:
---
int settings_read(const char *name, char *value, size_t valuesize);
int settings_save(const char *name, const char *value);
---
Every other module that wants to use the settings facilities will
include "settings.h" and user settings_read() and settings_write().
The implementation and any additional data (such as the filename) are
hidden in settings.c.

In C++ I was trying to create a class in settings.h, but I'm not sure
if I should add private data there:
---
class Settings {
  const char filename[] = "settings.ini";
public:
  void Settings(void);
  virtual ~Settings(void);
  int settings_read(const string name, string value);
  int settings_save(const string name, const string value);};

It looks like it shouldn't. Why did you put filename in Settings
class? I don't think anything forced you to do it.

However, same goes for your constructor and (virtual, no less)
destructor. From what you're explaining, you don't need Settings class
at all (but see ^^^).
I'm
tempted to avoid adding private data/functions in the class
declaration in settings.h, but in settings.c as typical static names
(like in C). I don't know if this is a good approach, because I have
seen many C++ source files with private names in include file.

Private non-static members that class implementation needs are inside
the class, yes. Private static members are more questionable. You can
do it, but it doesn't buy you anything. Possibly better solution is to
use anonymous namespace in the class' implementation and put your
static member there (it's not a class member then).


^^^ You might want to have Settings class e.g. to avoid repeatedly
opening and closing your file for situations where you'll be reading
several parameters at once. So then you might do:

class Settings
{
iostream& stream;
public:
Settings(iostream& stream) : stream_(stream) {}
read, write settings using stream_...
};

Attention: here, stream that you pass to settings must outlive
Settings. That's convenient for following (I'd say typical) usage:


iostream stream(...);
Settings settings(stream);
Use(settings);

So there you have one example of using a private member.

HTH,

Goran.
 
J

Jorgen Grahn

I have a medium experience in C and now I'm learning C++. I have some
difficulties to think by and use classes, so with object oriented
programming. ....
In C++ I was trying to create a class in settings.h, but I'm not sure
if I should add private data there:
---
class Settings {
const char filename[] = "settings.ini";
public:
void Settings(void);
virtual ~Settings(void);
int settings_read(const string name, string value);
int settings_save(const string name, const string value);
};
---
Why the user should know about private data, like filename? I'm
tempted to avoid adding private data/functions in the class
declaration in settings.h, but in settings.c as typical static names
(like in C). I don't know if this is a good approach, because I have
seen many C++ source files with private names in include file.

I think it's clearer if you write it like this (other bugs not fixed):

class Settings {
public:
void Settings(void);
virtual ~Settings(void);
int settings_read(const string name, string value);
int settings_save(const string name, const string value);
private:
const char filename[] = "settings.ini";
// other data, I'm sure
};

You can put as much private stuff as you need there -- the reader will
have to overlook it because it's private.

On the other hand, the way you seem to use 'filename' there is no
reason to have it in the class declaration at all. Put it somewhere in
settings.cpp. I'd use a const string in an anonymous namespace.

/Jorgen
 
J

Jorgen Grahn

If that design suffices for your purposes, then I don't see why you
couldn't use that exact same code in your C++ program as well. ....

One of the practical advantages of classes is that, like structs, you
can instantiate more than one at a time, and each instance will be
independent of each other, and they can co-exist at the same time. ....
However, just because there are classes doesn't necessarily mean that
everything *must* be a class. If someting can be implemented as a
function, and there's no need for anything else, then why not.

I agree, of course, that C++ doesn't mean you have to squeeze every
function into a class. And it's an imortant point to make when
talking to newbies (who have perhaps used Java).

But this case IMHO begs for a class holding the read data. Otherwise
his settings_read() and settings_save() would have to read and parse
the file at every call. Or he'd have to keep some global crud hidden
away in settings.cpp.

I also think he should separate writing to the settings, and writing
them to disk. That way he can drop the I/O error checks from his
read() and write() functions.

/Jorgen
 
M

MikeWhy

pozz said:
I have a medium experience in C and now I'm learning C++. I have some
difficulties to think by and use classes, so with object oriented
programming.

In my application I have a configuration file that stores some
settings in non-volatile way. Several parts, modules and classes could
access the configuration file both for reading and writing settings.

In C I can create settings.h with the interface:
---
int settings_read(const char *name, char *value, size_t valuesize);
int settings_save(const char *name, const char *value);
---
Every other module that wants to use the settings facilities will
include "settings.h" and user settings_read() and settings_write().
The implementation and any additional data (such as the filename) are
hidden in settings.c.

In C++ I was trying to create a class in settings.h, but I'm not sure
if I should add private data there:
---
class Settings {
const char filename[] = "settings.ini";
public:
void Settings(void);
virtual ~Settings(void);
int settings_read(const string name, string value);
int settings_save(const string name, const string value);
};
---
Why the user should know about private data, like filename? I'm
tempted to avoid adding private data/functions in the class
declaration in settings.h, but in settings.c as typical static names
(like in C). I don't know if this is a good approach, because I have
seen many C++ source files with private names in include file.

It's a very fair question.

In use, I should expect to see code similar to the following:

void foo()
{
Settings config("settings.ini");
int abc = config.read("xyz");
//...
config.save("xyzAbc");
};

Rewrite your class with this usage in mind.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top