The data types we studied in the previous lesson are each
used to declare a variable that holds a (single) value. As mentioned in the
previous lesson, each of these variables is also created in the stack memory.
After declaring the variable, you can initialize it with a value of your choice.
When the variable has been initialized, the value is "put" in the
memory where the variable resides. A data type used to declare such a variable
is called a value type. In the same way, when you create a class, by default, it
is a value type. To re-enforce the fact that the class is a value type, you can
precede its struct or class keyword with the value keyword. Here
is an example:
|
|
value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
|
value class CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
|
When introducing assemblies in Lesson 1, we saw that you
could control the "visibility" of a class outside of its assembly,
using the private or public keyword. To apply this to a value class, you can
precede the value keyword with private or public:
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
|
public value class CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
|
Practical
Learning: Creating a Value Class |
|
- To make the class a value type, change the file as follows:
#pragma once
public value struct CHouse
{
long PropertyNumber;
__wchar_t PropertyType;
unsigned Stories;
unsigned Bedrooms;
float Bathrooms;
unsigned YearBuilt;
double PropertyValue;
};
|
- Save the file
In the previous lesson and above, we saw how you could
declare a variable of a primitive type. This is the same way you declare a
variable of a value: the name of the class, followed by a name for the variable,
followed by a semi-colon. Here is an example:
using namespace System;
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CHouse home;
return 0;
}
As done with the primitive types, you can declare two or
more class variables with one type. Here are examples:
using namespace System;
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CHouse home;
CHouse singleFamily, townhouse;
home.Stories;
return 0;
}
|
When you declare a variable of a class, we say that you have created an
instance of the class, or that you have instantiated the class. The word
instance here means that the object is alive or has been made alive in your
program.
After declaring a value type, you can
access the members of its class. This is done using the member access operator ".".
To access a member,
type the name of the declared variable, followed by a period, followed by the
name of the member you want to access. For example, to access the YearBuilt member of
the above home variable you would write:
using namespace System;
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CHouse home;
home.YearBuilt;
return 0;
}
|
Using this syntax, you can display the value of a class
member:
using namespace System;
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CHouse home;
Console::WriteLine(home.YearBuilt);
return 0;
}
You can also use the cout class or the printf_s()
function to display the values of the object's members.
Techniques of Initializing an Object
|
|
There are various techniques used to initialize an object:
initializing individual members or initializing the object as a whole. To initialize a member of an object, access it and assign it
an appropriate value. Here is an example:
using namespace System;
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CHouse singleFamily;
singleFamily.Bathrooms = 2.5;
singleFamily.Stories = 3;
singleFamily.Value = 524885;
singleFamily.YearBuilt = 1962;
singleFamily.TypeOfHome = L'S';
singleFamily.Bedrooms = 5;
Console::Write("Type of Home: ");
Console::WriteLine(singleFamily.TypeOfHome);
Console::Write("Number of Bedrooms: ");
Console::WriteLine(singleFamily.Bedrooms);
Console::Write("Number of Bathrooms: ");
Console::WriteLine(singleFamily.Bathrooms);
Console::Write("Number of Stories: ");
Console::WriteLine(singleFamily.Stories);
Console::Write("Year Built: ");
Console::WriteLine(singleFamily.YearBuilt);
Console::Write("Monetary Value: ");
Console::WriteLine(singleFamily.Value);
return 0;
}
This would produce:
Type of Home: S
Number of Bedrooms: 5
Number of Bathrooms: 2.5
Number of Stories: 3
Year Built: 1962
Monetary Value: 524885
Press any key to continue . . .
Notice that we initialized the members in any order of our
choice. You can also initialize an object as a variable. This time,
type the name of the variable followed by the assignment operator, followed by
the desired values of the variables listed between an opening and a closing
curly brackets. Each value is separated with a comma. The first rule you must
observe is that the list of variables must follow the order of the declared
members of the class. The second rule you must observe is that none of the
members of the class can be another class. Here is an example:
using namespace System;
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CHouse singleFamily = { L'S', 5, 2.5, 3, 1962, 524885 };
Console::Write("Type of Home: ");
Console::WriteLine(singleFamily.TypeOfHome);
Console::Write("Number of Bedrooms: ");
Console::WriteLine(singleFamily.Bedrooms);
Console::Write("Number of Bathrooms: ");
Console::WriteLine(singleFamily.Bathrooms);
Console::Write("Number of Stories: ");
Console::WriteLine(singleFamily.Stories);
Console::Write("Year Built: ");
Console::WriteLine(singleFamily.YearBuilt);
Console::Write("Monetary Value: ");
Console::WriteLine(singleFamily.Value);
return 0;
}
Like any other variable,
before using an object, you must first declare it. Although the usual technique
consists of declaring an object where needed, C/ C++ supports another technique.
You can declare a variable next to the class. To do this, type the name of the
class between the closing curly bracket and the semi-colon. Here is an example:
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
} townhouse;
|
|
In this case, the townhouse variable is a valid instance of
the object and gives access to the members of the object. This means that you
can simply initialize any of its members as you see fit. Here is an example:
using namespace System;
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
} townhouse;
int main()
{
townhouse.YearBuilt = 1986;
townhouse.Bathrooms = 1.5;
townhouse.Stories = 3;
townhouse.Value = 348255;
townhouse.Bedrooms = 3;
townhouse.TypeOfHome = L'T';
Console::Write("Type of Home: ");
Console::WriteLine(townhouse.TypeOfHome);
Console::Write("Number of Bedrooms: ");
Console::WriteLine(townhouse.Bedrooms);
Console::Write("Number of Bathrooms: ");
Console::WriteLine(townhouse.Bathrooms);
Console::Write("Number of Stories: ");
Console::WriteLine(townhouse.Stories);
Console::Write("Year Built: ");
Console::WriteLine(townhouse.YearBuilt);
Console::Write("Monetary Value: ");
Console::WriteLine(townhouse.Value);
return 0;
}
This would produce:
Type of Home: T
Number of Bedrooms: 3
Number of Bathrooms: 1.5
Number of Stories: 3
Year Built: 1986
Monetary Value: 348255
Press any key to continue . . .
Just like you would declare more than one variable, you can
declare many instances of a class when creating the object. Here is an
example:
public value struct CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
} singleFamily, townhouse, comdominium;
Practical
Learning: Initializing an Object |
|
- To use the class as a type, change the Exercise.cpp file as follows:
#include "Property.h"
using namespace System;
int main()
{
CHouse townhouse;
townhouse.PropertyNumber = 872735;
townhouse.YearBuilt = 1986;
townhouse.Bathrooms = 1.5;
townhouse.Stories = 3;
townhouse.MarketValue = 348255;
townhouse.Bedrooms = 3;
townhouse.PropertyType = L'T';
Console::WriteLine("=//= Altair Realty =//=");
Console::WriteLine("-=- Properties Inventory -=-");
Console::Write("Property #: ");
Console::WriteLine(townhouse.PropertyNumber);
Console::Write("Type of Home: ");
Console::WriteLine(townhouse.PropertyType);
Console::Write("Number of Bedrooms: ");
Console::WriteLine(townhouse.Bedrooms);
Console::Write("Number of Bathrooms: ");
Console::WriteLine(townhouse.Bathrooms);
Console::Write("Number of Stories: ");
Console::WriteLine(townhouse.Stories);
Console::Write("Year Built: ");
Console::WriteLine(townhouse.YearBuilt);
Console::Write("Monetary Value: ");
Console::WriteLine(townhouse.MarketValue);
return 0;
}
|
- Execute the application to see the result
=//= Altair Realty =//=
-=- Properties Inventory -=-
Property #: 872735
Type of Home: T
Number of Bedrooms: 3
Number of Bathrooms: 1.5
Number of Stories: 3
Year Built: 1986
Monetary Value: 348255
Press any key to continue . . .
|
- Close the DOS window
Class Members Levels of Access
|
|
To exercise a good level of control over your class, you
"hide" some members and "expose" some others. This is done
by setting different levels of access for the member of the class. To do this, you will define
what members are
public and which ones are private. The members that are public are preceded with the public keyword followed by a
colon. The
others are considered private. Still, to specify that a member is private, you
can precede it with private:. Here are examples:
|
|
public value struct CHouse
{
private:
__wchar_t TypeOfHome;
int Bedrooms;
public:
double Bathrooms;
private:
Byte Stories;
int YearBuilt;
double Value;
private:
};
Notice that, so far, we didn't signal
any difference between a structure and a class, but there is one. In a
structure, if you don't specify the private and public members, all members considered
public. In a class, if you don't specify the private and public members, all members considered
private. Based on this, to show the level of access of the members of your class
(whether struct or class), precede each with the desired level: private:
or public:.
Notice that you can
create as many public: sections or as many private: sections as you want. When creating a class with different public and private
sections, all of the declared variables under an access level keyword abide by
the rules of that access level. The fact that you use different public sections
does not give different kinds of public levels to the variables. A variable
declared as public in one public section has the same public level of access as
any other variable that is declared in another public section. There is no rule
as to which section should come first. Simply remember that, for a class, if the
top members are not given a level of access, then they are private.
When a member is declared private, you cannot access it
outside of its class. Based on this rule, the following program will not
compile:
using namespace System;
public value class CHouse
{
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CHouse townhouse;
townhouse.YearBuilt = 1986;
townhouse.Bathrooms = 1.5;
townhouse.Stories = 3;
townhouse.Value = 348255;
townhouse.Bedrooms = 3;
townhouse.TypeOfHome = L'T';
return 0;
}
Remember that when an access level is not set for a class,
all of its members are private by default. The above program would produce the
following errors:
error C2248: 'CHouse::YearBuilt' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::YearBuilt'
see declaration of 'CHouse'
error C2248: 'CHouse::Bathrooms' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::Bathrooms'
see declaration of 'CHouse'
error C2248: 'CHouse::Stories' : cannot access private member declared
in class 'CHouse' .see declaration of 'CHouse::Stories'
see declaration of 'CHouse'
error C2248: 'CHouse::Value' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::Value'
see declaration of 'CHouse'
error C2248: 'CHouse::Bedrooms' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::Bedrooms'
see declaration of 'CHouse'
error C2248: 'CHouse::TypeOfHome' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::TypeOfHome'
see declaration of 'CHouse'
error C2248: 'CHouse::TypeOfHome' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::TypeOfHome'
see declaration of 'CHouse'
error C2248: 'CHouse::Bedrooms' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::Bedrooms'
see declaration of 'CHouse'
error C2248: 'CHouse::Bathrooms' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::Bathrooms'
see declaration of 'CHouse'
error C2248: 'CHouse::Stories' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::Stories'
see declaration of 'CHouse'
error C2248: 'CHouse::YearBuilt' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::YearBuilt'
see declaration of 'CHouse'
error C2248: 'CHouse::Value' : cannot access private member declared
in class 'CHouse' see declaration of 'CHouse::Value'
see declaration of 'CHouse'
The following program will not compile either:
using namespace System;
public value struct CHouse
{
private:
__wchar_t TypeOfHome;
int Bedrooms;
public:
double Bathrooms;
private:
Byte Stories;
int YearBuilt;
double Value;
private:
};
int main()
{
CHouse townhouse;
townhouse.YearBuilt = 1986;
townhouse.Bathrooms = 1.5;
townhouse.Stories = 3;
townhouse.Value = 348255;
townhouse.Bedrooms = 3;
townhouse.TypeOfHome = L'T';
Console::Write("TypeOfHome: ");
Console::WriteLine(townhouse.TypeOfHome);
Console::Write("Number of Bedrooms: ");
Console::WriteLine(townhouse.Bedrooms);
Console::Write("Number of Bathrooms: ");
Console::WriteLine(townhouse.Bathrooms);
Console::Write("Number of Stories: ");
Console::WriteLine(townhouse.Stories);
Console::Write("Year Built: ");
Console::WriteLine(townhouse.YearBuilt);
Console::Write("Monetary Value: ");
Console::WriteLine(townhouse.Value);
return 0;
}
This time, although this is a structure, the members that
have been marked as private are no longer accessible outside of the class.
Practical
Learning: Controlling the Access to a Class |
|
- To make the CHouse a class, access the Property.h file and change it as
follows:
#pragma once
public value class CHouse
{
public:
long PropertyNumber;
__wchar_t PropertyType;
unsigned Stories;
unsigned Bedrooms;
float Bathrooms;
unsigned YearBuilt;
double MarketValue;
};
|
- Execute the application to see the result
- Close the DOS window
|
Just as you can type-define the name of a built-in
data type, you can do the same for any class. As reviewed for primitive
types, when doing this, remember that you are not creating a new type: you
are only providing a pseudo-name for an existing class. Here is an
example:
public value class CHouse
{
public:
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
typedef CHouse Home;
Home singleFamily;
return 0;
}
|
You can also type-define a class outside of any
function to make the name global.
Just as you can create a constant of a built-in data
type, you can also create a constant of a class. Always
remember that the constant refers to a value that doesn't change and the
constant value must be initialized with a known or already defined value.
Here is an example:
using namespace System;
public value class CHouse
{
public:
__wchar_t TypeOfHome;
int Bedrooms;
double Bathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
const CHouse singleFamily = { L'S', 5, 2.5, 3, 1962, 524885 };
Console::Write("Type of Home: ");
Console::WriteLine(singleFamily.TypeOfHome);
Console::Write("Number of Bedrooms: ");
Console::WriteLine(singleFamily.Bedrooms);
Console::Write("Number of Bathrooms: ");
Console::WriteLine(singleFamily.Bathrooms);
Console::Write("Number of Stories: ");
Console::WriteLine(singleFamily.Stories);
Console::Write("Year Built: ");
Console::WriteLine(singleFamily.YearBuilt);
Console::Write("Monetary Value: ");
Console::WriteLine(singleFamily.Value);
return 0;
}