Home

Value Types

 

Introduction

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:

House
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 LearningPractical Learning: Creating a Value Class

  1. 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;
    };
  2. Save the file

Creating a Value Type

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;
}
House

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 LearningPractical Learning: Initializing an Object

  1. 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;
    }
  2. 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 . . .
  3. 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 LearningPractical Learning: Controlling the Access to a Class

  1. 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;
    };
  2. Execute the application to see the result
  3. Close the DOS window

Type-Defining a Class

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.

Constant Objects

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;
}
 

Previous Copyright © 2006 FunctionX, Inc. Next