In the code below, I've created a constructor for the class drink which initialises the variables name and price. Why am I able to assign default values to these variables when they have not yet been declared in the code, at the point of assignment?
Secondly, when creating the object coke of type drink, I am able to declare it with and without explicitly specifying that it is the object of a class, for example:
class drink coke;
...And...
drink coke;
Is there any difference between declaring objects one way or the other? Is one way more widely accepted or traditionally used?
Is it better to create a constructor as a private or public member function? Is it even considered a member function? If there is a preference or more approved way, why?
These are all the questions I have so far. I will use this thread to ask more questions as I continue to learn more about classes, if that is acceptable. Any help you can provide is much appreciated.
Why am I able to assign default values to these variables when they have not yet been declared in the code, at the point of assignment?
Classes are special case. All class member are able to interact with member variables even if they are defined later in code.
Is there any difference between declaring objects one way or the other? Is one way more widely accepted or traditionally used?
No. In C++ it is preferably to drop explicit class/struct mention.
Is it better to create a constructor as a private or public member function?
Usually you want your constructor to be public to be able to construct your class. However there are a bunch of reasons why you might want your constructors or some of them to be private (singleton is one example).
Is it even considered a member function?
Yes. It is a special specific member function. (special member function is a term in Standard with another meaning. Default constructor is, however, a special function)
If there is a preference or more approved way, why?
When using classes, is it more common to incorporate inheritance, with an overarching generic base class and layers of (possibly branching) derived classes, or to use one big class to contain every little bit of possible data and functionality you might need?
Just from writing this question down I can sense that it is most probably the former due to logical modularity, but I'll ask anyway just to be sure.
In the code below I am trying to access the public member function attack() but the compiler seems to think I am trying to access the private member variable attack and gives me an error. I would have thought the parentheses were enough to distinguish between the two. Is the only way to get around this problem to change the name of either attack or attack()?
For example you can have a Mob class which has health, attack, etc. Then you need to create another kind of mob which can attack at a distance. One way will be to create a subclass called RangedMob and do work here, but in fact you should consider just giving a Mob a member called attack_type. It might be a simple enumeration value at first, transforming in fullfledged class with own behavior later.
2) In your case problem is encountered earlier: you have two members called attack. It does not matter that they are of different types, they have the same name. And you cannot have two entities with same name declared in same scope.
Error log for my compiler:
||=== Build: Debug in Test (compiler: GNU GCC 4.9.1x64) ===|
\Test\main.cpp|55|error: 'void Player::attack()' conflicts with a previous declaration|
\Test\main.cpp|38|note: previous declaration 'int Player::attack'|
\Test\main.cpp||In constructor 'Player::Player()':|
\Test\main.cpp|47|error: invalid use of member (did you forget the '&' ?)|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 3 second(s)) ===|
Is there any reason to use a member initialisation list in a constructor, other than to initialise const member variables, over initialising the values normally inside the body of the constructor?
Is the : in a member initialisation list context referred to as the member initialisation operator?
Is there any reason to use a member initialisation list in a constructor
there is no reasons to not to.
When you don't, you are first creating default initialized members incurring construction cost, and then copy-assign new value to it, incurring assigment cost.
With member init list, you just creating them in-place. No additional overhead after creation.
Is the : in a member initialisation list context referred to as the member initialisation operator?
No, there is no member initialisation operator in C++. It this context : merely denotes start of init list.
Should the class access specifiers be indented or not? I'm wondering because when using Code::Blocks the access specifiers are automatically unindented.
Is this the proper way to set up a class and use member initialisation when using multiple files?
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13
#include <iostream>
#include "Test.h"
usingnamespace std;
int main()
{
Test object(10);
cout << object.getVal();
return 0;
}
#ifndef TEST_H
#define TEST_H
class Test
{
private:
int val;
public:
Test(int x);
int getVal();
};
#endif
In Test.h I include only the class definition with the member variable and the function declarations. I leave the function definitions to Test.cpp, as I believe is correct.
Yes, it is good to separate group of entities related to single responsibility to their own file/files.
It increases maintainability and allows for more efficient code reuse.
As far as I understand, making class members private is to stop objects of that class from directly accessing them. To access the data, public access functions (Getters and Setters) are used instead. Considering the fact that objects of a class cannot access members of another class anyway, regardless of access level, why is this done? Shouldn't objects be able to freely access and utilise their own properties and functionalities?
class foo
{
public:
int i;
};
class bar
{
public:
void accept(foo& f)
{
f.i = 10; //Changing member of passed object;
}
};
int main()
{
foo x;
x.i = 5; //Changing member of class
bar b;
b.accept(x); // Changing member by another class.
};
Shouldn't objects be able to freely access and utilise their own properties and functionalities?
Emphasis mine. They sure should, but their own members only.
If I understand that right, you are referencing the object x of class foo and assigning it's member variable i a new value in the public function of class bar.
Okay, so is passing objects of one class to another class, by reference, via public member functions, the only way to access and potentially modify public member variables and functions of other class objects?
...you need to change that object? That is the reasong why passing by reference exist in C++.
When you are overloading IO operators you usually need to take stream by reference and change it by calling another operator.
No, what I mean is, since encapsulation is pretty much essential to OOP, is there any reason you might want to access the public members of a class object from a different class object? I wouldn't think there are any reasons, and that if it happens, it's because a mistake was made.
Instead, If you wanted to access the members of another class, composition would be the correct technique to use, wouldn't it?
Encapsulation may be a fundamental part of OOP, but there is no reason for it to be forced on all programmers. It is possible that a programmer could use a public member variable and it might not be bad design, it could be done via getter/setter methods but many people say these break encapsulation. Composition is the correct method if one class contains another. I'm pretty sure composition doesn't change this anyway because access specifiers still apply when objects are composed of other objects. Especially with simple things, it is often unnecessary to fully encapsulate simple, small classes.