Difference between assign values for the variables of a class [duplicate] - class

This question already has answers here:
Should I initialize variable within constructor or outside constructor [duplicate]
(11 answers)
Closed 6 years ago.
What is the difference between below 2 ways of assigning values for variables of a class.
Class A{
Private Variable v = someValue;
}
vs
Class A{
private Variable v;
//constructor
public A(){
this.v = someValue;
}
}
Can someone please explain?

There is no real difference from a code execution point of view.
As a previous answer says, I prefer declaring the variable outside of the constructor; for example:
public class A {
private int aValue = 100;
}
Instead of
public class A {
private int aValue;
public A() {
this.aValue = 100;
}
}
The reason being that if you have multiple constructors, you do not have to keep writing this.aValue = 100; and you are unable to "forget" to initialize the variable in a constructor.
As others have said however, there are times when it is better to initialize the variable in the constructor.
If it will change based on values passed to it via the constructor, obviously initialize it there.
If the variable you are initializing may throw an error and you need to use try / catch - it is clearly better to initialize it in the constructor
If you are working on a team that uses a specific coding standard and they require you to initialize your variables in the constructor, you should do so.
Given freedom and none of the above, I still declare it at the top - makes it much easier to find all of your variables in one place (in my experience).
See this duplicate answer: https://stackoverflow.com/a/3919225/1274820

What is the difference between below 2 ways of assigning values for
variables of a class.
Generally nothing, but ...
class constructor is an entry point when creating a new instance, so all assignments should be done there for readability and maintainability.
When you want create a new instance you start reading a source code at the constructor. Here is an example. All informations about new instance are in one proper place.
public class C {
private int aValue;
private int bValue;
private int cValue;
private int dValue;
public C(int a, int b) {
this.aValue = a;
this.bValue = b;
this.cValue = a * b;
this.dValue = 1000;
}
}

If you look at the MSIL of this class:
namespace Demo
{
public class MyClass
{
private string str = "hello world";
private int b;
public MyClass(int b)
{
this.b = b;
}
}
}
.method public hidebysig specialname rtspecialname
instance void .ctor(int32 b) cil managed
{
// Code size 25 (0x19)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldstr "hello world"
IL_0006: stfld string Demo.MyClass::str <---- RIGHT HERE
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: ldarg.0
IL_0012: ldarg.1
IL_0013: stfld int32 Demo.MyClass::b
IL_0018: ret
} // end of method MyClass::.ctor
You can see that the constructor is "injected" with the assignment of this.str = "hello world".
So once your code is compiled, there is no difference what so ever. Yet, there are quite a few good reasons why you should not do it (user1274820's answer has some them)

Related

Initialize and modify class variables in derived classes

I want to initialize a variable class for my Base class and modify it only in some children classes.
The initialization of this class variable is in the header:
class Base{
public:
Base();
int a = 1;
The header of my derived class is:
class ChildA : public Base{
public:
ChildA ();
int a = 2;
}
Problem
I tried to run this:
Base classe*;
classe = new ChildA();
std::cout << classe->a << std::endl;
The problem is that, instead of printing 2 as I expected, it prints 1 (value initialized in my parent class). For other derived classes, I want classe->a to still return 1.
How can I solve this?
What you are seeing are the results of upcasting - having a base class point to a derived class object.
I highly recommend you read more on the topic, but a simplified picture is that the base class "carries" the whole object (base and derived content), but can access only it's original, own content. This is why you see a value from the base class rather than the derived class.
Lippman's C++ Primer has a very comprehensive explanation of upcasting, downcasting, object slicing, and other inheritance-related concepts. This includes implementing virtual functions which give you the functionality to invoke derived class functions through an interface that's common with base.
|----------------|-----------------|
| a (for Base) | a (for ChildA) |
|----------------|-----------------|
\________________/
^
|_ classe
Sorry if my drawing is not that good! As you can see in the above picture, when you create an object of type ChildA, this object contains a part for keeping the data members of the base class (i.e. Base) and another part for the data members of derived class (i.e. ChildA). Considering the fact that you have a pointer to the base class (i.e. classe), this pointer only allows you to access the base member variables and methods. So calling classe->a, returns the Base::a for you, that is 1.
If you change the type of classe pointer into ChildA, in that case calling classe->a will return 2, because it refers to the a inside the derived class, i.e. ChildA::a.
For other derived classes, I want classe->a to still return 1. How can
I solve this?
If you need in some derived classes to access different as, it is better to have a virtual function in the base class and override the base function if needed:
class Base {
public:
Base() {}
virtual int getA() { return a; }
private:
int a = 1;
};
class ChildA : public Base
{
public:
ChildA() {}
int a = 2;
};
class ChildB : public Base
{
public:
ChildB() {}
int getA() { return a; }
private:
int a = 2;
};
Now by calling getA() on a pointer of Base or ChildA, you will have 1, but calling getA on an object of type ChildB will return 2.

What do I need to do in order to ask, if an pointer to an abstract class in instance of a child class?

I need some help to understand everything correctly.
I want to check a pointer to a abstract class if it is instance of a specific child class.
I have one abstract class "kunde" and two child classes "firmenkunde" and "privatkunde" who inherit the methods of kunde.
In order to search by "int knr" (int customer number) I use as return type a pointer to "kunde".
Within the database class I get back the "kdstatus" and use
kunde * kd = new privatkunde(0);
if the status is PK or new firmenkunde(0) if it would be FK.
The abstract class kunde doesn't have any attribute I could use to save the status.
This way I did hope to be able to ask, if the returned pointer would be an instance of the class privatkunde or firmenkunde. But I did not found any method to do this.
MessageBox::Show(marshal_as<String^>(typeid(kd).name()));
I did ask the typeid name but this only returns "class kunde *" and is not what I want to know.
Is there a way to work around this problem?
You can use typeid as you mentioned. Using the polymorphism, you can write:
kunde * kd = new privatkunde(0);
if(typeid(kd) == typeid(privatkunde))
{
// This is a privatkunde objet
}
See here to have more explanation.
The problem you encounter is that your kunde class is not polymorphic. As commented by #George, see how the virtual methods work.
I hope it can help.
Generally you can use dynamic_cast for this.
An example:
class Parent
{
public:
virtual ~Parent();
virtual void do_thing()= 0;
};
class Child1: public Parent
{
public:
void do_thing() override
{
//...
}
};
class Child2: public Parent
{
public:
void do_thing() override
{
//...
}
};
void use_parent(Parent* p)
{
auto c1_ptr = dynamic_cast<Child1*>(p);
if(c1_ptr != nullptr)
{
// p is a Child1
do_thing_with_child1(c1_ptr);
}
auto c2_ptr = dynamic_cast<Child2*>(p);
if(c2_ptr != nullptr)
{
// p is a Child2
do_thing_with_child2(c2_ptr);
}
}
While this works, it becomes difficult to maintain if you have multiple child classes. You have to remember to add a case for each new child class you define.
A better way to structure something like this would be to use the "Tell, don't ask" concept when designing your object-oriented systems. A great write-up on this concept can be found here.

Interface pointers C++

I can't express my question in words. Please look the code below, I hope you will understand my question.
I have a class and an interface as shown below.
class MyInterface
{
public:
virtual ~MyInterface(){}
virtual void print() = 0;
};
class MyClass : public MyInterface
{
public:
MyClass(){}
~MyClass(){}
void print()
{
printf("Hello World\n");
}
};
Now here's my question.
MyClass* myclass = new MyClass();
myclass->print(); //will print "Hello World"
MyInterface* pMyInterface = (MyInterface*)myclass;
pMyInterface->print();
Will the second call print Hello World as well? If yes, then why?
One note is that you do not need to explicitly cast to an accessible base class, like you do in MyInterface* pMyInterface = (MyInterface*)myclass;. It is an implicit conversion from a pointer/reference to a derived class to that of an accessible base class.
In fact, such casting may introduce bugs if the classes are unrelated.
Find more details in virtual function specifier.

Genie's writeonly property

I read it from vala tutorial
for readonly: vala
public int b { get; private set; }
in Genie:
prop readonly b: int
for writeonly:
Vala:
public int b { private get; set; }
Genie: [this line: syntax error]
prop writeonly b: int
How to declare an one-line writeonly property in Genie?
maybe something like?
prop XXX b: int
We can write a FOUR lines writeonly property:
class Wonly
_b: int
prop b: int
set
_b = value
init
var w = new Wonly
// print w.b // ERROR!! writeonly!!
w.b = 456 // OK
but How to write an one-line writeonly property?
I will do my best to answer your question here, however some aspects of your question are not clear. Maybe it would be help to give a bit more context, explaining better what you are planning to achieve and a little bit more of code for contextualization.
That said, I will assume you are asking about the syntax for class properties in Genie.
Properties are ways of hiding the implementation details from the users of the class you developed. According to Vala's tutorial this move is also called the information hiding principle in computer science.
In Vala, a propertie would be defined within a in the following way:
static int current_year = 2525;
class Person : Object {
private int year_of_birth = 2493;
public int age {
get { return current_year - year_of_birth; }
set { year_of_birth = current_year - value; }
}
}
In Genie, it would look like this:
class Foo : Object
prop name : string
prop readonly count : int
[Description(nick="output property", blurb="This is the output property of the Foo class")]
prop output : string
get
return "output"
set
_name = value
Now for the write only properties. It is a bit of a controversial matter based on this and this questions at SO. It seems to be useful only when you are not planning to read what you write. But as you can see on the questions above, most of the answers suggest the creation of methods instead of using write only properties.
That takes us to the syntax you are pointing to:
public int b { private get; set; }
You state that this is the syntax to a write only property in Vala, and it seems to be true. This is because, by setting the get as private you prevent the user to read the value. You can make the get or set as private in Vala by leaving it out of the set block as well, ie, in Vala you could simply remove the private get part.
Now this is where I am unsure, but I suggest you try it out in your code. Based on Vala's ability to set private getters or setters by removing them from the set block, I suspect that the same applies to Genie.
I removed the setting of the get from the following code and it compiled:
[indent=4]
class Foo : Object
prop name : string
prop readonly count : int
[Description(nick="output property", blurb="This is the output property of the Foo class")]
prop output : string
set
_name = value
init
var foo = new Foo()
Maybe that is what you are looking for, but I am not sure it would work in real code. If it does not, perhaps you would be better off with methods instead.

How non-static is accessible in static context in this program?

I am having confusion with the following code:
class A
{
int x;
static void F(B b) {
b.x = 1; /* Ok,
I want to know how is this ok, in a static block how a non static
instance variables are called because as I know that static block
gets memory at compile time before execution of a single command
while non static at run time and static method accessing a non static
variable which is not created yet please elaborate me on this
*/
}
}
class B: A
{
static void F(B b) {
b.x = 1; // Error, x not accessible
}
}
Nothing gets memory at compile time. Static fields are indeed placed in the static block of memory when the type gets initialized. Call stacks for static methods are allocated at run time exactly like in case of instance methods.
Now, why static methods don't have access to the instance fields. Consider this:
class A {
public int Value;
static int GetValue() {
return Value;
}
}
There you have a class with an instance field and a static method. Now, somewhere else you try this:
var a1 = new A();
a1.Value = 5;
var a2 = new A();
a2.Value = 10;
int result = A.GetValue();
Now, if compiler allowed this, what value would the result get? 5 or 10 or something else? This just doesn't make sense, because static methods are declared for class as a whole and aren't aware of instances of this class. So in the code of static method you don't know how many (if any) instances of this class exist and can't access their instance fields.
Hope this makes a little sense.
Either you changed the code in question a bit or I didn't read very carefully. Seems like it's completely different problem right now. The variable x is indeed not accessible for the class B because of its level of protection (default in C# is private). Class A can modify X because it's declared in class A and visible to its method. Class B can't do it (you must make x protected or public for that).