class data member or member function argument?

  • Thread starter Dwight Army of Champions
  • Start date
D

Dwight Army of Champions

When designing a class, how do you know whether to make a variable a
private data member or just an argument to the class's member
functions? If I make it a private data member, then it's imperative I
have a valuie for it at the time I create the object (put it in the
constructor). On the other hand, if I just use it as a member function
argument, then I have to be responsible for defining and initializing
the variable before the object is created, and then deleting the
variable after the object is deleted. THis leads to code like this:

// code begins here
// ... define and initialize many variables called MyVariable

MyClass* MyObject = new MyClass(this);

MyObject->DoSomething(MyVariable1, MyVariable2, /* ... */ );
MyObject->DoSomethingElse(MyVariable2, MyVariable6);

delete MyObject; MyObject = 0;

// delete many MyVariables
// code ends here

What is the best way to do this?
 
R

Robert Fendt

And thus spake Dwight Army of Champions
When designing a class, how do you know whether to make a variable a
private data member or just an argument to the class's member
functions? If I make it a private data member, then it's imperative I
have a valuie for it at the time I create the object (put it in the
constructor). On the other hand, if I just use it as a member function

A variable is made a member of the class precisely when it is
part of an object's state. If and when that is the case depends
mostly on the problem that is being solved.

Of course you can implement two-phase construction (i.e. provide
functions that 'fill in' object state information after the
object has been actually created). But in that case you have to
be *very* careful of undefined behaviour of your objects (e.g.
when someone calls a function without having called the needed
setup functions first). This essentially violates encapsulation
and is thus very bad mojo.
argument, then I have to be responsible for defining and initializing
the variable before the object is created, and then deleting the
variable after the object is deleted. THis leads to code like this:

This does not make much sense. *Of course* you have to have the
data ready that is needed for a function to run. Whether the
data is part of the object (in form of members) or you feed it
to the function at call time does not change the simple fact
that you have to have all the bits and pieces together that are
needed for that particular function to run.

The 'deleting' part is largely moot, at least if you stay clear
of needless 'naked' heap allocation (and that's bad practice
anyway). Only use 'new' and 'delete' if it is absolutely
necessary that an object 'survives' exiting the currect scope
(and consider smart pointer templates even then).
What is the best way to do this?

The best way to do this is to buy a book on object oriented
software design, read it carefully and then try again. Sorry if
that sounds harsh, but it seems to me that your problem is not
how to implement a specific pattern in C++ but rather how
object-orientation and encapsulation is supposed to work in
general. And for that, comp.lang.c++ is just not the right
place, in my opinion.

Regards,
Robert
 
O

osmium

:

When designing a class, how do you know whether to make a variable a
private data member or just an argument to the class's member
functions? If I make it a private data member, then it's imperative I
have a valuie for it at the time I create the object (put it in the
constructor). On the other hand, if I just use it as a member function
argument, then I have to be responsible for defining and initializing
the variable before the object is created, and then deleting the
variable after the object is deleted.

My guess is you are missing some fundamentals here. Focus on what deleting
an object does. The member function is gone after you delete the object.
What did the member function consist of? I didn't look at your code, only
your question.
 
D

Dwight Army of Champions

OK I definitely need to get a book on object oriented software design.
Recommendations?
 
T

tonydee

When designing a class, how do you know whether to make a variable a
private data member or just an argument to the class's member
functions? If I make it a private data member, then it's imperative I
have a valuie for it at the time I create the object (put it in the
constructor). On the other hand, if I just use it as a member function
argument, then I have to be responsible for defining and initializing
the variable before the object is created, and then deleting the
variable after the object is deleted. THis leads to code like this:

// code begins here
// ... define and initialize many variables called MyVariable

MyClass* MyObject = new MyClass(this);

MyObject->DoSomething(MyVariable1, MyVariable2, /* ... */ );
MyObject->DoSomethingElse(MyVariable2, MyVariable6);

delete MyObject; MyObject = 0;

// delete many MyVariables
// code ends here

What is the best way to do this?

I agree buying a book on OO is a good idea, but can't recommend any.

Just to summarise very briefly, a class is generally used to represent
a type of "entity" in your program: something you could say "I've got
one of those". It might be an employee, a cat, a car, a line in a
file. Then, you can create your objects to represent individual
instances of these concepts. You want to put private data into the
class so that someone using the class can just say "I want one
employee record here", or "I'm going to use a list of cats", but they
don't need additional variables to record any specifics of an
individual cat, because the cat class itself wraps up all the data
about each cat.

You've got a couple mechanisms to avoid new and delete everywhere, and
having to explicitly initialise data members or local data. One is
scoping: the idea that your program is broken up into chunks of work -
namely a scope delimited with { and }, and variables can be placed
inside that scope. If they are classes, their constructor will run
and can initialise them to some default value, or you can typically
explicitly request a value. The object's destructor is then called at
the end of that scope, so you don't have to put anything in your code
to reclaim the memory. For example:

int fn()
{
std::string x = "hello";
std::cout << x << '\n';
std::list<Cat> cats;
cats.push_back("Bluey");
feed(cats);
}

fn() doesn't need any news or deletes. Similarly, in a class, you can
have data members that are STL containers and don't need explicit
initialisation.

class Cat
{
public:
Cat(const std::string& name, int age) : name_(name), age_(age)
{ }
int get_age() const { return age_; }
const std::string& name() const { return name_; }
private:
std::string name_;
int age_;
};

Again, all the memory allocation is taken care of for you. The way
the constructor is written ensures you'll have to supply a name and
age when creating an object instance, ala:

Cat cat("Smokey", 4);

Cheers,
Tony
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top