Question about nesting classes[local and nested] - c++

I have a class A.Now this has a method say performSomething(). This essentially takes a LINE as input and checks what type of LINE it is and branches accordingly and perform the intended task;
Class A
{
performSomething( LINE )
{
check LINE TYPE
switch( LINE ) {
}
}
};
Now, Im being asked to introduce a new inner class to do this operation in it. Now, here comes the trouble. Im not at all sure what he means by that or if that actually makes any sense here!.
Thing is I NEED LINE(input parameter) if I need to proceed further. But if I chose to design the new class as a LOCAL class(class inside method), then I can't access it[as local auto variable are not accessible];[i posted a question on this too).
I neither feel that this can be addressed by using NESTED class(class inside class);But Im, not quite sure about it.
He also insists that the LINE will be available in the nested class and so I need not worry about it. But what's breaking my head is that this line is not an instance variable. It is jus t an AUtomatic variable.
So, please someone point me out if this can be achieved thorough nested classes.
Thanks,
Moanr Pavan.

Well, there's quite a bit wrong with the code so far.
For instance, the switch is very likely the wrong approach to polymorphism. In C++ we generally use virtual functions for that, but sometimes we can also use function overloading and/or templates (if the actual types are already known at compile time).
Secondly, there's no rationale stated for an "inner" class, nor is it clear what that means. You can have classes inside other classes, and even classes inside functions. So the following would be syntactically OK:
class A
{
void performSomething( LINE )
{
class B {
static void performSomething(A* that, LINE) { code };
};
B::performSomething(this, LINE);
}
};
Your compiler will accept this, but we have to ask: what's the point of this? Also, note that B::performSomething can only access the members from A if we explicitly pass this.

Related

C++ What's the right way to run, in a superclass constructor, code that relies on lots of variables that the subclass overrides?

Say I have a superclass that, when it initializes, wants to run some code that relies on a whole bunch of class variables that may or may not be overridden by a subclass in its constructor.
What's the accepted, clean way to code that?
I feel like I'm having a brain fart; this should be a standard, beginner usage of inheritance, but I can't figure it out.
e.g. say I have a superclass that represents a vehicle, and when it starts, I want to do a whole bunch of code where it processes, say, the load per axle or something (doesn't matter) but that code uses as inputs a bunch of parameters that exist for all vehicles (and thus exist in the superclass), say weight, length, numwheels, numaxles, maybe even complicated data structures defining how many wheels per axle, etc.).
The various subclasses (sportscar, bigrig, motorcycle), want to set the weight, length, numwheels, numaxles, etc. before the superclass does its processing.
Super::Super() {
Process(var1_,var2_,var3_,var4_, ...);
}
Sub1::Sub1(): Super() {
var1_ = <some math>;
var2_ = <some math>;
...
}
doesn't work because the superclass Process() runs before the vars get set by the subclass. Right?
Super::Super(float var1, WackyDatastructureDef var2, int var3, WackyStruct2 var4, ...),
var1_(var1), var2_(var2), var3_(var3), ............... {
Process(var1_,var2_,var3_,var4_, ...);
}
Sub1::Sub1(): Super(<some math>, <some math>, <some math>, <some math>, ......) {
....
}
looks horrible for obvious reasons. Also, it looks like a pain if I only need to override 2 out of the 20 default variable values.
Super::Super() {}
void Super::Init() {
Process(var1_, var2_, var3_, var4_ ...... );
}
Sub1::Sub1(): Super() {
var1_ = <some math>;
var2_ = <some math>;
...
Init();
}
looks the cleanest but I don't like it... it's weird to have to remember to call Init() at the end of all my subclass constructors. What if another programmer wants to subclass off my superclass and doesn't know my magic rule?
What's the right way to do this?
There are many ways to solve this issue (lack of virtual constructors in C++). Each one has its own benefits and drawbacks. Most common patterns to workaround this limitation:
Pass all required arguments to base class constructor. This can be really annoying if you need more than few parameters. Code will be less and less readable and pretty hard to extend if requirements change. Of course it has a big benefit: it's not a workaround and everyone will understand it.
Change your design (this may be the best thing to do but it may require a lot of work). If you need a lot of parameters then you may pack all arguments in separate class, it'll hold object status. Base class constructor will just accept one parameter of this type and it'll contain its status (or just its initialization data but this is another story). Its benefit is to keep design clear (no workaround like for first solution) but it may involve some complexity if this initialization token will evolve with its own class hierarchy.
Add a public initialization method. Change your Init() method to public, it won't be invoke by derived constructors but by class users. This will allow you to add initialization code in each derived class (and initialization order is then controlled by implementation itself). This method is pretty old school and it requires users will call it but it has one big benefit: it's universally known and it won't astonish anyone. See this post here on SO for a small discussion about them.
Virtual constructor idiom. See this article for a reference. It works as intended and you can make it easier to use with few template methods. IMO biggest disadvantage is that it changes how you manage inheritance and initialization when you create a new derived class. This may be boring and error prone and prolix. Moreover you change how a class is instantiated too and, for me, this is always annoying.
Few notes about second solution (from comments). If you apply this I see at least these options:
Stupid entity (just data, no logic) that holds all required parameters.
Encapsulate object status in a separate object. Object you pass from derived classes is not used and dropped but it'll be part of object.
In both cases you can have or not a parallel hierarchy for parameters (BaseParametersHolder, DerivedParametersHolder and so on). Please note that holder doesn't suffer from same problem of first solution (many arguments) because creation can be delegated to a private function (example is to illustrate concept, code is far to be nice):
class Derived : public Base
{
public:
Derived() : Base(CreateParameters())
{
}
private:
ParameterHolder CreateParameters()
{
ParameterHolder parameters;
parameters.Value = 1;
parameters.AnotherValue = 2;
return parameters;
}
};
What to use? There is not an answer. I'd prefer to be consistent across code (so if you decide to use holders then use them everywhere, do not mix - for example - with v.i. idiom). Just pick proper one each time and try to be consistent.
Pass the relevant information up to the base class constructor.

Instance-level encapsulation with C++

I have a two-part question. First, I understand that C++ provides only class-level data encapsulation, meaning that all objects of the same class have access to one another's private members. I understand the reason for this, but have found some links (i.e. http://www.programmerinterview.com/index.php/c-cplusplus/whats-the-difference-between-a-class-variable-and-an-instance-variable/) which appear to contradict this point, suggesting that I could do the following:
class testclass {
private:
// Below would be an instance-level variable, and new memory for it is set aside
// in each object I create of class testclass
int x;
// Below would be a class-level variable, memory is set aside only once no matter
// how many objects of the same class
static int y;
}
What I would like to do is actually make this work, i.e., I would like to define a variable in a class which is private in each instantiation (this is my second question). Since the code snippet above does not appear to achieve this, is there a work around I can use to create data that is private to individual objects? Thank you!
EDIT:
It's true that I'm still learning OO basics. I'll use the ubiquitous car example to show what I'm trying to do, which I'm sure must be a common thing to try. I'd welcome any suggestions for how to rethink it:
class car {
private:
int mileage;
public:
car(int); // Constructor
void odometer();
};
car::car(int m) {
mileage = m;
}
void car::odometer() {
return mileage;
}
int main(void) {
car ford(10000), honda(20000);
cout<<ford.odometer(); //Returns 20000, since honda constructor overwrites private variable 'mileage'
}
Is there any way to get the odometer() method to return the mileage of either the ford or honda, depending on what I want?
Priviledge (public, private, protected) only applies to names. Only during the time when a name is resolved will the compiler apply permissions. Once compiled, all such information is gone.
In your example above, all uses of the names x and y within a scope that resolves to THOSE variables will be private to your class. Only functions declared in your class, be they static or not, will be able to access those variables by name.
All bets are off however if you give out the variable to other objects that can then refer to the variable by other names which have other permissions.
I'm not sure what you're asking with reference to "in each instantiation". AFAIK, there is no native way to make a variable private such that only that instance can access it. In all cases, instances can access each other's private parts.
There's some ways you could get around this I suppose. First is to templatize your class and give each instance a different type. You could do this with an integer template parameter or something. This could make life annoying though as you try to work with these types as the same kind of thing. You'd have to virtualize and have an abstract base class or something.
Currently that's the only method I can think of. All others depend on calling entities playing nice.
Generally speaking it's rare that you'd want to protect members from other instances. The usual case of the same type being passed to the same type is during copy and assignment, where you basically need all knowledge about the source to correctly copy. My bet is that you need to rethink what you're trying to do, whatever that is.

Sharing function between classes

I have three classes which each store their own array of double values. To populate the arrays I use a fairly complex function, lets say foo(), which takes in several parameters and calculates the appropriate values for the array.
Each of my three classes uses the same function with only minor adjustments (i.e. the input parameters vary slightly). Each of the classes is actually quite similar although they each perform separate logic when retrieving the values of the array.
So I am wondering how should I 'share' the function so that all classes can use it, without having to duplicate the code?
I was thinking of creating a base class which contained the function foo() and a virtual get() method. My three classes could then inherit this base class. Alternatively, I was also thinking perhaps a global function was the way to go? maybe putting the function into a namespace?
If the classes have nothing in common besides this foo() function, it is silly to put it in a base class; make it a free function instead. C++ is not Java.
Declaring of a function in base class sounds the most appropriate solution. Not sure if you need virtual "get" though, instead just declare the array in the base class and provide access method(s) for descendants.
More complex part is "the input parameters vary slightly". If parameters differ by type only then you may write a template function. If difference is more significant than the only solution I see is splitting main function into several logic blocks and using these blocks in descendant classes to perform final result.
If your classes are quite similar, you could create a template class with three different implementations that has the function foo<T>()
Implement that function in base class. If these classes are similar as you say, they should be derived from one base class anyway! If there are several functions like foo(), it might be reasonable in some cases to combine them into another class which is utilized by/with your classes.
If the underlying data of the class is the same (Array of doubles), considering using a single class and overloading the constructor, or just use 3 different functions:
void PopulateFromString(const string&)
void PopulateFromXml(...)
void PopulateFromInteger(...)
If the data or the behavior is different in each class type, then your solution of base class is good.
You can also define a function in the same namespace as your classes as utility function, if it has nothing to do with specific class behavior (Polymorphism). Bjarne StroupStroup recommends this method by the way.
For the purpose of this answer, I am assuming the classes you have are not common in any other outwards way; they may load the same data, but they are providing different interfaces.
There are two possible situations here, and you haven't told us which one it is. It could be more like
void foo(double* arr, size_t size) {
// Some specific code (that probably just does some preparation)
// Lots of generic code
// ...
// Some more specific code (cleanup?)
}
or something similar to
void foo(double* arr, size_t size) {
// generic_code();
// ...
// specific_code();
// generic_code();
// ...
}
In the first case, the generic code may very well be easy to put into a separate function, and then making a base class doesn't make much sense: you'll probably be inheriting from it privately, and you should prefer composition over private inheritance unless you have a good reason to. You could put the new function in its own class if it benefits from it, but it's not strictly necessary. Whether you put it in a namespace or not depends on how you're organising your code.
The second case is trickier, and in that case I would advise polymorphism. However, you don't seem to need runtime polymorphism for this, and so you could just as well do it compile-time. Using the fact that this is C++, you can use CRTP:
template<typename IMPL>
class MyBase {
void foo(double* arr, size_t size) {
// generic code
// ...
double importantResult = IMPL::DoALittleWork(/* args */);
// more generic code
// ...
}
};
class Derived : MyBase<Derived> {
static double DoALittleWork(/* params */) {
// My specific stuff
return result;
}
};
This gives you the benefit of code organisation and saves you some virtual functions. On the other hand, it does make it slightly less clear what functions need to be implemented (although the error messages are not that bad).
I would only go with the second route if making a new function (possibly within a new class) would clearly be uglier. If you're parsing different formats as Andrey says, then having a parser object (that would be polymorphic) passed in would be even nicer as it would allow you to mock things with less trouble, but you haven't given enough details to say for sure.

dynamical binding or switch/case?

A scene like this:
I've different of objects do the similar operation as respective func() implements.
There're 2 kinds of solution for func_manager() to call func() according to different objects
Solution 1: Use virtual function character specified in c++. func_manager works differently accroding to different object point pass in.
class Object{
virtual void func() = 0;
}
class Object_A : public Object{
void func() {};
}
class Object_B : public Object{
void func() {};
}
void func_manager(Object* a)
{
a->func();
}
Solution 2: Use plain switch/case. func_manager works differently accroding to different type pass in
typedef enum _type_t
{
TYPE_A,
TYPE_B
}type_t;
void func_by_a()
{
// do as func() in Object_A
}
void func_by_b()
{
// do as func() in Object_A
}
void func_manager(type_t type)
{
switch(type){
case TYPE_A:
func_by_a();
break;
case TYPE_B:
func_by_b();
default:
break;
}
}
My Question are 2:
1. at the view point of DESIGN PATTERN, which one is better?
2. at the view point of RUNTIME EFFCIENCE, which one is better? Especailly as the kinds of Object increases, may be up to 10-15 total, which one's overhead oversteps the other? I don't know how switch/case implements innerly, just a bunch of if/else?
Thanks very much!
from the view point of DESIGN PATTERN, which one is better?
Using polymorphism (Solution 1) is better.
Just one data point: Imagine you have a huge system built around either of the two and then suddenly comes the requirement to add another type. With solution one, you add one derived class, make sure it's instantiated where required, and you're done. With solution 2 you have thousands of switch statements smeared all over the system and it is more or less impossible to guarantee you found all the places where you have to modify them for the new type.
from the view point of RUNTIME EFFCIENCE, which one is better? Especailly as the kinds of Object
That's hard to say.
I remember a footnote in Stanley Lippmann's Inside the C++ Object Model, where he says that studies have shown that virtual functions might have a small advantage against switches over types. I would be hard-pressed, however, to cite chapter and verse, and, IIRC, the advantage didn't seem big enough to make the decision dependent on it.
The first solution is better if only because it's shorter in code. It is also easier to maintain and faster to compile: if you want to add types you need only add new types as headers and compilation units, with no need to change and recompile the code that is responsible for the type mapping. In fact, this code is generated by the compiler and is likely to be as efficient or more efficient than anything you can write on your own.
Virtual functions at the lowest level cost no more than an extra dereference in a table (array). But never mind that, this sort of performance nitpicking really doesn't matter at this microscopic numbers. Your code is simpler, and that's what matters. The runtime dispatch that C++ gives you is there for a reason. Use it.
I would say the first one is better. In solution 2 func_manager will have to know about all types and be updated everytime you add a new type. If you go with solution 1 you can later add a new type and func_manager will just work.
In this simple case I would actually guess that solution 1 will be faster since it can directly look up the function address in the vtable. If you have 15 different types the switch statement will likely not end up as a jump table but basically as you say a huge if/else statement.
From the design point of view the first one is definitely better as thats what inheritance was intended for, to make different objects behave homogeneously.
From the efficiency point of view in both alternatives you have more or less the same generated code, somewhere there must be the choice making code. Difference is that inheritance handles it for you automatically in the 1st one and you do it manually in the 2nd one.
Using "dynamic dispatch" or "virtual dispatch" (i.e. invoking a virtual function) is better both with respect to design (keeping changes in one place, extensibility) and with respect to runtime efficiency (simple dereference vs. a simple dereference where a jump table is used or an if...else ladder which is really slow). As a slight aside, "dynamic binding" doesn't mean what you think... "dynamic binding" refers to resolving a variable's value based on its most recent declaration, as opposed to "static binding" or "lexical binding", which refers to resolving a variable by the current inner-most scope in which it is declared.
Design
If another programmer comes along who doesn't have access to your source code and wants to create an implementation of Object, then that programmer is stuck... the only way to extend functionality is by adding yet another case in a very long switch statement. Whereas with virtual functions, the programmer only needs to inherit from your interface and provide definitions for the virtual methods and, walla, it works. Also, those switch statements end up all over the place, and so adding new implementations almost always requires modifying many switch statements everywhere, while inheritance keeps the changes localized to one class.
Efficiency
Dynamic dispatch simply looks up a function in the object's virtual table and then jumps to that location. It is incredibly fast. If the switch statement uses a jump table, it will be roughly the same speed; however, if there are very few implementations, some programmer is going to be tempted to use an if...else ladder instead of a switch statement, which generally is not able to take advantage of jump tables and is, therefore, slower.
Why nobody suggests function objects? I think kingkai interested in solving the problem, not only that two solutions.
I'm not experienced with them, but they do their job:
struct Helloer{
std::string operator() (void){
return std::string("Hello world!");
}
};
struct Byer{
std::string operator() (void){
return std::string("Good bye world!");
}
};
template< class T >
void say( T speaker){
std::cout << speaker() << std::endl;
}
int main()
{
say( Helloer() );
say( Byer() );
}
Edit: In my opinion this is more "right" approach, than classes with single method (which is not function call operator). Actually, I think this overloading was added to C++ to avoid such classes.
Also, function objects are more convenient to use, even if you dont want templates - just like usual functions.
In the end consider STL - it uses func objects everywhere and looks pretty natural. And I dont even mention Boost

C++: Copy constructor: Use getters or access member vars directly?

I have a simple container class with a copy constructor.
Do you recommend using getters and setters, or accessing the member variables directly?
public Container
{
public:
Container() {}
Container(const Container& cont) //option 1
{
SetMyString(cont.GetMyString());
}
//OR
Container(const Container& cont) //option 2
{
m_str1 = cont.m_str1;
}
public string GetMyString() { return m_str1;}
public void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
}
In the example, all code is inline, but in our real code there is no inline code.
Update (29 Sept 09):
Some of these answers are well written however they seem to get missing the point of this question:
this is simple contrived example to discuss using getters/setters vs variables
initializer lists or private validator functions are not really part of this question. I'm wondering if either design will make the code easier to maintain and expand.
Some ppl are focusing on the string in this example however it is just an example, imagine it is a different object instead.
I'm not concerned about performance. we're not programming on the PDP-11
EDIT: Answering the edited question :)
this is simple contrived example to
discuss using getters/setters vs
variables
If you have a simple collection of variables, that don't need any kind of validation, nor additional processing then you might consider using a POD instead. From Stroustrup's FAQ:
A well-designed class presents a clean
and simple interface to its users,
hiding its representation and saving
its users from having to know about
that representation. If the
representation shouldn't be hidden -
say, because users should be able to
change any data member any way they
like - you can think of that class as
"just a plain old data structure"
In short, this is not JAVA. you shouldn't write plain getters/setters because they are as bad as exposing the variables them selves.
initializer lists or private validator functions are not really
part of this question. I'm wondering
if either design will make the code
easier to maintain and expand.
If you are copying another object's variables, then the source object should be in a valid state. How did the ill formed source object got constructed in the first place?! Shouldn't constructors do the job of validation? aren't the modifying member functions responsible of maintaining the class invariant by validating input? Why would you validate a "valid" object in a copy constructor?
I'm not concerned about performance. we're not programming on the PDP-11
This is about the most elegant style, though in C++ the most elegant code has the best performance characteristics usually.
You should use an initializer list. In your code, m_str1 is default constructed then assigned a new value. Your code could be something like this:
class Container
{
public:
Container() {}
Container(const Container& cont) : m_str1(cont.m_str1)
{ }
string GetMyString() { return m_str1;}
void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
};
#cbrulak You shouldn't IMO validate cont.m_str1 in the copy constructor. What I do, is to validate things in constructors. Validation in copy constructor means you you are copying an ill formed object in the first place, for example:
Container(const string& str) : m_str1(str)
{
if(!valid(m_str1)) // valid() is a function to check your input
{
// throw an exception!
}
}
You should use an initializer list, and then the question becomes meaningless, as in:
Container(const Container& rhs)
: m_str1(rhs.m_str1)
{}
There's a great section in Matthew Wilson's Imperfect C++ that explains all about Member Initializer Lists, and about how you can use them in combination with const and/or references to make your code safer.
Edit: an example showing validation and const:
class Container
{
public:
Container(const string& str)
: m_str1(validate_string(str))
{}
private:
static const string& validate_string(const string& str)
{
if(str.empty())
{
throw runtime_error("invalid argument");
}
return str;
}
private:
const string m_str1;
};
As it's written right now (with no qualification of the input or output) your getter and setter (accessor and mutator, if you prefer) are accomplishing absolutely nothing, so you might as well just make the string public and be done with it.
If the real code really does qualify the string, then chances are pretty good that what you're dealing with isn't properly a string at all -- instead, it's just something that looks a lot like a string. What you're really doing in this case is abusing the type system, sort of exposing a string, when the real type is only something a bit like a string. You're then providing the setter to try to enforce whatever restrictions the real type has compared to a real string.
When you look at it from that direction, the answer becomes fairly obvious: rather than a string, with a setter to make the string act like some other (more restricted) type, what you should be doing instead is defining an actual class for the type you really want. Having defined that class correctly, you make an instance of it public. If (as seems to be the case here) it's reasonable to assign it a value that starts out as a string, then that class should contain an assignment operator that takes a string as an argument. If (as also seems to be the case here) it's reasonable to convert that type to a string under some circumstances, it can also include cast operator that produces a string as the result.
This gives a real improvement over using a setter and getter in a surrounding class. First and foremost, when you put those in a surrounding class, it's easy for code inside that class to bypass the getter/setter, losing enforcement of whatever the setter was supposed to enforce. Second, it maintains a normal-looking notation. Using a getter and a setter forces you to write code that's just plain ugly and hard to read.
One of the major strengths of a string class in C++ is using operator overloading so you can replace something like:
strcpy(strcat(filename, ".ext"));
with:
filename += ".ext";
to improve readability. But look what happens if that string is part of a class that forces us to go through a getter and setter:
some_object.setfilename(some_object.getfilename()+".ext");
If anything, the C code is actually more readable than this mess. On the other hand, consider what happens if we do the job right, with a public object of a class that defines an operator string and operator=:
some_object.filename += ".ext";
Nice, simple and readable, just like it should be. Better still, if we need to enforce something about the string, we can inspect only that small class, we really only have to look one or two specific, well-known places (operator=, possibly a ctor or two for that class) to know that it's always enforced -- a totally different story from when we're using a setter to try to do the job.
Do you anticipate how the string is returned, eg. white space trimmed, null checked, etc.? Same with SetMyString(), if the answer is yes, you are better off with access methods since you don't have to change your code in zillion places but just modify those getter and setter methods.
Ask yourself what the costs and benefits are.
Cost: higher runtime overhead. Calling virtual functions in ctors is a bad idea, but setters and getters are unlikely to be virtual.
Benefits: if the setter/getter does something complicated, you're not repeating code; if it does something unintuitive, you're not forgetting to do that.
The cost/benefit ratio will differ for different classes. Once you're ascertained that ratio, use your judgment. For immutable classes, of course, you don't have setters, and you don't need getters (as const members and references can be public as no one can change/reseat them).
There's no silver bullet as how to write the copy constructor.
If your class only has members which provide a copy constructor that creates
instances which do not share state (or at least do not appear to do so) using an initializer list is a good way.
Otherwise you'll have to actually think.
struct alpha {
beta* m_beta;
alpha() : m_beta(new beta()) {}
~alpha() { delete m_beta; }
alpha(const alpha& a) {
// need to copy? or do you have a shared state? copy on write?
m_beta = new beta(*a.m_beta);
// wrong
m_beta = a.m_beta;
}
Note that you can get around the potential segfault by using smart_ptr - but you can have a lot of fun debugging the resulting bugs.
Of course it can get even funnier.
Members which are created on demand.
new beta(a.beta) is wrong in case you somehow introduce polymorphism.
... a screw the otherwise - please always think when writing a copy constructor.
Why do you need getters and setters at all?
Simple :) - They preserve invariants - i.e. guarantees your class makes, such as "MyString always has an even number of characters".
If implemented as intended, your object is always in a valid state - so a memberwise copy can very well copy the members directly without fear of breaking any guarantee. There is no advantage of passing already validated state through another round of state validation.
As AraK said, the best would be using an initializer list.
Not so simple (1):
Another reason to use getters/setters is not relying on implementation details. That's a strange idea for a copy CTor, when changing such implementation details you almost always need to adjust CDA anyway.
Not so simple (2):
To prove me wrong, you can construct invariants that are dependent on the instance itself, or another external factor. One (very contrieved) example: "if the number of instances is even, the string length is even, otherwise it's odd." In that case, the copy CTor would have to throw, or adjust the string. In such a case it might help to use setters/getters - but that's not the general cas. You shouldn't derive general rules from oddities.
I prefer using an interface for outer classes to access the data, in case you want to change the way it's retrieved. However, when you're within the scope of the class and want to replicate the internal state of the copied value, I'd go with data members directly.
Not to mention that you'll probably save a few function calls if the getter are not inlined.
If your getters are (inline and) not virtual, there's no pluses nor minuses in using them wrt direct member access -- it just looks goofy to me in terms of style, but, no big deal either way.
If your getters are virtual, then there is overhead... but nevertheless that's exactly when you DO want to call them, just in case they're overridden in a subclass!-)
There is a simple test that works for many design questions, this one included: add side-effects and see what breaks.
Suppose setter not only assigns a value, but also writes audit record, logs a message or raises an event. Do you want this happen for every property when copying object? Probably not - so calling setters in constructor is logically wrong (even if setters are in fact just assignments).
Although I agree with other posters that there are many entry-level C++ "no-no's" in your sample, putting that to the side and answering your question directly:
In practice, I tend to make many but not all of my member fields* public to start with, and then move them to get/set when needed.
Now, I will be the first to say that this is not necessarily a recommended practice, and many practitioners will abhor this and say that every field should have setters/getters.
Maybe. But I find that in practice this isn't always necessary. Granted, it causes pain later when I change a field from public to a getter, and sometimes when I know what usage a class will have, I give it set/get and make the field protected or private from the start.
YMMV
RF
you call fields "variables" - I encourage you to use that term only for local variables within a function/method