struct
is the old C way of doing things.
struct Point { int x, y; }; Point p; // Note lack of new cout << p.x << '\n'; // uninitialized value p.x = 8; p.y = 9; cout << p.x << ',' << p.y << '\n';
c.cc:5: warning: 'p.main()::Point::x' is used uninitialized in this function 0 8,9
public
& private
define sections of the class.
class Point { public: Point(int a, int b) { x = a; y = b; } // constructor (alias ctor) int get_x() const { return x; } // accessor int get_y() const { return y; } // accessor void go_right() { x++; } // mutator private: int x, y; // Hands off! };
To make a class
work for output, define operator<<
appropriately:
class Point { public: Point(int a, int b) { x = a; y = b; } // ConstrucTOR int get_x() const { return x; } // accessor int get_y() const { return y; } // accessor void go_right() { x++; } // mutator private: int x, y; // Hands off! }; ostream &operator<<(ostream &out, const Point &p) { return out << p.get_x() << ',' << p.get_y(); } int main() { Point p(12, 34); cout << p << '\n'; // invoke operator<< }
12,34
class Quoted { string s; public: Quoted(const string &word) : s(word) { } string get() const { return "“" + s + "”"; } }; ostream &operator<<(ostream &os, const Quoted &rhs) { return os << rhs.get(); } int main() { Quoted name("Robert Bruce Banner"); cout << "I am " << name << ".\n"; }
I am “Robert Bruce Banner”.
s
is private
const
reference
operator<<
is not a method
private:
& public:
Methods can be defined inside or outside of the class.
class Quoted { string s; public: Quoted(const string &word) : s(word) { } string get() const; // declaration only }; string Quoted::get() const { return "“" + s + "”"; } ostream &operator<<(ostream &os, const Quoted &rhs) { return os << rhs.get(); } int main() { Quoted name("Slartibartfast"); cout << "I am " << name << ".\n"; }
I am “Slartibartfast”.
public
, private
,
or protected
.
private
for a class
, public
for a struct
.
public
: anyone can access them
private
: nobody except other methods of this class can access them
protected
: can be accessed by this class, and by immediately derived class
class Foo { // A class, with a variable of each type public: int pub; // I’m public! private: int priv; // I’m private! protected: int prot; // I’m a little teapot, short & stout. }; int main() { Foo f; f.pub = 1; // great // f.priv = 2; // nope // f.prot = 2; // nope return f.pub; }
One class can declare another class/method/function to be its friend:
class Foo { friend class Bar; friend double Zip::zulu(int) const; friend int alpha(); friend std::ostream &operator<<(std::ostream &os, const Foo &); private: int x,y; };
class Bar
can access our data.
zulu(int) const
of the class Zip
.
alpha()
.
operator<<(ostream &, const Foo &)
.
class A
, via friend class B
, offers friendship to class B
.
C
is D
’s friend, then D
is not necessarily C
’s friend.
E
& F
are friends, and F
& G
are friends,
then E
& G
are strangers.
H
is I
’s friend, and I
is the parent of J
,
then H
& J
are strangers.
K
is L
’s parent, then K
& L
are strangers.
friend
declarations,
and overuse them.
friend
should be your last tool, not your first one.
friend
declarations to avoid the overhead
of method calls, then you have no faith in current compilers.
They’re quite good at inlining methods.