class person {
public:
string first; // first name
string last; // last name
person(string firstName,string lastName) {
first=firstName;
last=lastName;
}
};
int foo(void) {
person p("Doc","Lawlor");
cout<<"My name: "<<p.first<<" "<<p.last<<"\n";
return 0;
}
You can use a special and hideous "initializer" syntax for initializing
your class members from your constructor. This does exactly the
same thing as above:class person {
public:
string first; // first name
string last; // last name
person(string firstName,string lastName)
:first(firstName), //<- call "first"'s constructor with "firstName"
last(lastName)
{
cout<<"Made a person.\n";
}
};
int foo(void) {
person p("Doc","Lawlor");
cout<<"My name: "<<p.first<<" "<<p.last<<"\n";
return 0;
}
Here's a simpler example of the initializer syntax:
class gotta_int {
public:
int my_int;
gotta_int(void)
:my_int(3) // <- initialize my_int
{ /* don't need anything here! */ }
};
int foo(void) {
gotta_int g;
return g.my_int;
}
The initializer list begins with a colon, and then you initialize each
member by name, passing the parameters for that member's
constructor.
If you've got several members to initialize, you separate the members
with a
comma. Initializers are always run in the order that you declared
the data members, NOT the order you list the initializers! Using
the initializer syntax is good because it avoids calling the
default constructor and then the assignment operator for each member,
which is a little more efficient, and works for members without
assignment operators.class thing : public string //<- "thing" is also a "string"The "thing" inherited the "append" and "at" methods from its parent. It has its own integer, though.
{
public:
int my_int;
};
int foo(void) {
thing t;
t.my_int=2; // it's a class...
t.append("WHY!?"); // ..but it's *also* a string!?
cout<<"Its int is "<<t.my_int<<" and its second letter is "<<t.at(1)<<"\n";
return 0;
}
class person : public string //<- we *are* a string: our first nameLike cloning, the child shares nearly all the features of the parent (member data, member functions, static members, even most operators), but can add new features of its own. The only thing the child doesn't inherit is the parent's constructors (except those the child calls explicitly), assignment operators, and friends.
{
public:
string last; // last name
person(string firstName,string lastName)
:string(firstName), //<- call parent class's constructor
last(lastName)
{
cout<<"Made a person.\n";
}
};
int foo(void) {
person p("Doc","Lawlor");
cout<<"My name: "<<p<<" "<<p.last<<"\n";
return 0;
}
class person : public string //<- we *are* a string: our first nameYou can even inherit from several different classes, called "multiple inheritance". You then glom together the methods, members, and data from all your parent classes. This is usually a terrible idea, but the language supports it!
{
public:
string last; // last name
person(string firstName,string lastName)
:string(firstName), //<- call parent class's constructor
last(lastName)
{
cout<<"Made a person.\n";
}
};
class old_person : public person //<- we *are* a person
{
public:
int age;
old_person(int ageNow,string firstName,string lastName)
:person(firstName,lastName), // must call parent constructor first
age(ageNow) // ... then you can initialize your own members
{
cout<<"...an old person.\n";
}
};
int foo(void) {
old_person p(33,"Doc","Lawlor");
cout<<"My name: "<<p<<" "<<p.last<<", age "<<p.age<<"\n";
return 0;
}
class A {
public:
int from_A;
A(void) :from_A(2) {} // constructor
};
class B {
public:
string from_B;
B(void) :from_B("I was once a man... like you!") {} // constructor
};
class C : public A, public B // Multiple inheritance: C inherits from both A and B
{
public:
void print(void) {
cout<<"I inherited both "<<from_A<<" and '"<<from_B<<"'\n";
}
};
int foo(void) {
C kid;
kid.print();
return kid.from_A;
}
There are a few times inheritance is useful, and C++ provides a lot of
interesting features to support those times (such as the "virtual"
method we'll cover next week). However, inheritance is often
overused, in situations where plain object containment like above would
work much better. I used to have my classes inherit stuff from
all over the place, but I don't use inheritance very often now!