It will be easier to start learning C++ from a good book, instead of immediately trying to play with it on your own. C++ isn't as tolerant of mistakes as Lua is.
Still, here's some C++ code similar to your Lua example:
// Makes the standard type std::string available:
#include <string>
// Every variable needs a type.
// "class" creates a new type with given members, so here's how we'll define
// a type for variable "foo".
// A class definition like this usually goes in a header file.
class FooType
{
public:
// These members have default initializers, which will be used when
// a FooType object is created without its own initializer.
int a = 0;
std::string b = "hello";
std::string c = "world";
// This declares a class member function named bar, returning nothing:
void bar();
};
// The actual variable foo:
FooType foo;
// Defining the member function called FooType::bar :
// This might go in a source file which begins with an #include of
// the corresponding header file.
#include <iostream> // to get std::cout and std::endl
void FooType::bar()
{
// self.a = self.a + 1 :
// The C++ keyword "this" is similar to Lua's "self", but is a pointer.
// All of these are equivalent:
// (*this).a = (*this).a + 1;
// this->a = this->a + 1;
// a = a + 1; // C++ automatically adds an implicit "this->" when you
// just name a member.
// ++a; // A shortcut for adding one to a number.
++a;
// print(self.b.." "..self.c) :
std::cout << b << " " << c << std::endl;
// Lua's print automatically adds a newline after its data, but
// C++ std::cout does not. The std::endl adds a newline and then
// "flushes" the output, making sure it gets sent out more or less
// immediately instead of waiting for more data as an optimization.
// table.insert(self, baz) :
// Not possible - C++ does not allow adding members to a class which
// aren't declared in the class definition. If you really need something
// similar, you could use a map with name as the key, but then you would
// need to access all those "members" via that map, not with a plain
// obj.name expression.
}
Some differences to note:
In Lua, the colon method syntax is just a shortcut. That is, foo:bar(t)
is exactly the same as foo.bar(foo, t)
, but Lua would let you do weird things like foo.bar(0, t)
meaning the self
variable becomes 0
. (This might of course violate the implied contract of the bar
method!) In C++, compilers will often implement member functions as though they're ordinary functions with an extra parameter for this
, but as far as the language is concerned, a member function is entirely different from a non-member function, and the only ways to call it all involve an object of the correct type to become *this
.
Related, Lua lets you reassign self
, but C++ does not let you change the pointer this
.
Lua treats tables with "reference semantics", but the default in C++ is that all variables use "value semantics".
-- Lua:
foo2 = foo -- Another name for the same table.
foo2.a = 3 -- foo.a is now 3.
// C++ (within a function):
FooType foo2 = foo; // A different independent object.
foo2.a = 3; // foo2.a is 3, but foo.a is unchanged
FooType& foo3 = foo; // Another name for object foo.
foo3.a = 4; // foo.a is now 4.