There really isn't any reason you can't. In C, you only had pointers. C++ introduces references and it is usually the preferred way in C++ is to pass by reference. It produces cleaner code that is syntactically simpler.
Let's take your code and add a new function to it:
#include <iostream> #include "Rectangle.h" void changestuff(Rectangle& rec); void changestuffbyPtr(Rectangle* rec); int main() { Rectangle rect; rect.set_x(50); rect.set_y(75); std::cout << "x,y: " << rect.get_x() << rect.get_y() << sizeof(rect) << std::endl; changestuff(rect); std::cout << "x,y: " << rect.get_x() << rect.get_y() << std::endl; changestuffbyPtr(&rect); std::cout << "x,y: " << rect.get_x() << rect.get_y() << std::endl; Rectangle* rectTwo = new Rectangle(); rectTwo->set_x(15); rectTwo->set_y(30); std::cout << "x,y: " << rectTwo->get_x() << rectTwo->get_y() << std::endl; changestuff(*rectTwo); std::cout << "x,y: " << rectTwo->get_x() << rectTwo->get_y() << std::endl; changestuffbyPtr(rectTwo); std::cout << "x,y: " << rectTwo->get_x() << rectTwo->get_y() << std::endl; std::cout << rectTwo << std::endl; } void changestuff(Rectangle& rec) { rec.set_x(10); rec.set_y(11); } void changestuffbyPtr(Rectangle* rec) { rec->set_x(10); rec->set_y(11); }
Difference between using the stack and heap:
#include <iostream> #include "Rectangle.h" Rectangle* createARect1(); Rectangle* createARect2(); int main() { // this is being created on the stack which because it is being created in main, // belongs to the stack for main. This object will be automatically destroyed // when main exits, because the stack that main uses will be destroyed. Rectangle rect; // rectTwo is being created on the heap. The memory here will *not* be released // after main exits (well technically it will be by the operating system) Rectangle* rectTwo = new Rectangle(); // this is going to create a memory leak unless we explicitly call delete on r1. Rectangle* r1 = createARectangle(); // this should cause a compiler warning: Rectangle* r2 = createARectangle(); } Rectangle* createARect1() { // this will be creating a memory leak unless we remember to explicitly delete it: Rectangle* r = new Rectangl; return r; } Rectangle* createARect2() { // this is not allowed, since when the function returns the rect will no longer // exist since its stack was destroyed after the function returns: Rectangle r; return &r; }
It should also be worth mentioning that a huge difference between pointers and references is that you can not create a reference that is uninitialized. So this perfectly legal:
int *b;
while this is not:
int& b;
A reference has to refer to something. This makes references basically unusable for polymorphic situations, in which you may not know what the pointer is initialized to. For instance:
// let's assume A is some interface: class A { public: void doSomething() = 0; } class B : public A { public: void doSomething() {} } class C : public A { public: void doSomething() {} } int main() { // since A contains a pure virtual function, we can't instantiate it. But we can // instantiate B and C B* b = new B; C* c = new C; // or A* ab = new B; A* ac = new C; // but what if we didn't know at compile time which one to create? B or C? // we have to use pointers here, since a reference can't point to null or // be uninitialized A* a1 = 0; if (decideWhatToCreate() == CREATE_B) a1 = new B; else a1 = new C; }
new?