Logo

Visual C++ Keywords: __abstract

 

C++ Abstract Classes

In C++, a class is referred to as abstract if it serves (only) as a base or parent for other classes. That is, you cannot declare a variable of that class nor can you use it as you would a regular class. To create an abstract class in C++, at least one of its methods must be pure virtual. A pure virtual method is one that is not implemented or defined in that class. It is created using = 0; on its right side when declaring it.

Here is an example of a C++ abstract class with one pure virtual method:

public __gc class CSquare
{
public:
	virtual double Perimeter() = 0;
};

Managed C++ Abstract Classes

In managed C++, to indicate that a class will be used only as a parent for other classes, create it as abstract by using the __abstract keyword. The keyword precedes the name of the class.

Here is an example:

Header File: quadrilateral.h

#pragma once

public __abstract __gc class CQuadrilateral
{
};
 

You don't have to define any method for the abstract class but you can. As with C++, you can create either only regular methods, only pure virtual methods, or a mix. Here is an example of a constructor, a destructor, and two pure virtual methods for the above class:

Header File: quadrilateral.h

#pragma once

public __abstract __gc class CQuadrilateral
{
public:
	CQuadrilateral(void);
	virtual ~CQuadrilateral(void);
protected:
	virtual double Perimeter(void) = 0;
	virtual double Area(void) = 0;
};

Source Code: quadrilateral.cpp

#include "StdAfx.h"
#include ".\quadrilateral.h"
#using <mscorlib.dll>

CQuadrilateral::CQuadrilateral(void)
{
}

CQuadrilateral::~CQuadrilateral(void)
{
}
 

After creating an abstract class, you can derive a class from it. The first rule you must observe is that, a derived class must implement any pure virtual method that the parent class has. In other words, if you derive a class from the above abstract class, you must define your version of the above Perimeter() and the above Area() methods, otherwise, the derived class also would be considered abstract.

Here is an example of a class called CSquare that is based on the above CQuadrilateral class:

Header File: Square.h

#pragma once
#include "quadrilateral.h"

public __gc class CSquare :	public CQuadrilateral
{
public:
	CSquare(void);
	virtual ~CSquare(void);
	void setSide(double s);
protected:
	double side;
public:
	double getSide(void);
	virtual double Perimeter(void);
	virtual double Area(void);
};

Source Code: square.cpp

#include "StdAfx.h"
#include ".\square.h"
#using <mscorlib.dll>

CSquare::CSquare(void)
	: side(0)
{
}

CSquare::~CSquare(void)
{
}

void CSquare::setSide(double s)
{
	side = s;
}

double CSquare::getSide(void)
{
	return side;
}

double CSquare::Perimeter(void)
{
	return side * 4;
}

double CSquare::Area(void)
{
	return side * side;
}

If you try declaring a variable from the above CQuadrilateral class, you would receive an error.

The error produced is Error C3622: 'CQuadrilateral': a class declared as '__abstract' cannot be instantiated.

On the other hand, since the above CSquare class is not abstract, you can use it in your program as you see fit. Here is an example:

Header File: square.h
#pragma once
#include "quadrilateral.h"

public __gc class CSquare :	public CQuadrilateral
{
public:
	CSquare(void);
	virtual ~CSquare(void);
	void setSide(double s);
protected:
	double side;
public:
	double getSide(void);
	virtual double Perimeter(void);
	virtual double Area(void);
};
Source File: square.h
#include "StdAfx.h"
#include ".\square.h"
#using <mscorlib.dll>

CSquare::CSquare(void)
	: side(0)
{
}

CSquare::~CSquare(void)
{
}

void CSquare::setSide(double s)
{
	if( s <= 0.00 )
		side = 0.00;
	else
		side = s;
}

double CSquare::getSide(void)
{
	return side;
}

double CSquare::Perimeter(void)
{
	return side * 4;
}

double CSquare::Area(void)
{
	return side * side;
}

The class can then be used in an application by declaring an instance of it. Here is an example:

 

#pragma once

#include ".\square.h"

namespace Figures1
{
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <summary> 
	/// Summary for Form1
	///
	/// WARNING: If you change the name of this class, you will need to change the 
	///          'Resource File Name' property for the managed resource compiler tool 
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public __gc class Form1 : public System::Windows::Forms::Form
	{	
	public:
		Form1(void)
		{
			InitializeComponent();
		}
  
	protected:
		void Dispose(Boolean disposing)
		{
			if (disposing && components)
			{
				components->Dispose();
			}
			__super::Dispose(disposing);
		}
	private: System::Windows::Forms::GroupBox *  groupBox1;
	private: System::Windows::Forms::Button *  btnClose;
	private: System::Windows::Forms::Button *  btnCalculate;
	private: System::Windows::Forms::TextBox *  txtArea;
	private: System::Windows::Forms::TextBox *  txtPerimeter;
	private: System::Windows::Forms::TextBox *  txtSide;
	private: System::Windows::Forms::Label *  label3;
	private: System::Windows::Forms::Label *  label2;
	private: System::Windows::Forms::Label *  label1;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container * components;

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->groupBox1 = new System::Windows::Forms::GroupBox();
			this->btnClose = new System::Windows::Forms::Button();
			this->btnCalculate = new System::Windows::Forms::Button();
			this->txtArea = new System::Windows::Forms::TextBox();
			this->txtPerimeter = new System::Windows::Forms::TextBox();
			this->txtSide = new System::Windows::Forms::TextBox();
			this->label3 = new System::Windows::Forms::Label();
			this->label2 = new System::Windows::Forms::Label();
			this->label1 = new System::Windows::Forms::Label();
			this->groupBox1->SuspendLayout();
			this->SuspendLayout();
			// 
			// groupBox1
			// 
			this->groupBox1->Controls->Add(this->btnClose);
			this->groupBox1->Controls->Add(this->btnCalculate);
			this->groupBox1->Controls->Add(this->txtArea);
			this->groupBox1->Controls->Add(this->txtPerimeter);
			this->groupBox1->Controls->Add(this->txtSide);
			this->groupBox1->Controls->Add(this->label3);
			this->groupBox1->Controls->Add(this->label2);
			this->groupBox1->Controls->Add(this->label1);
			this->groupBox1->Location = System::Drawing::Point(16, 16);
			this->groupBox1->Name = S"groupBox1";
			this->groupBox1->Size = System::Drawing::Size(280, 136);
			this->groupBox1->TabIndex = 1;
			this->groupBox1->TabStop = false;
			this->groupBox1->Text = S"Square Processing";
			// 
			// btnClose
			// 
			this->btnClose->Location = System::Drawing::Point(184, 96);
			this->btnClose->Name = S"btnClose";
			this->btnClose->TabIndex = 7;
			this->btnClose->Text = S"Close";
			this->btnClose->Click += new System::EventHandler(this, btnClose_Click);
			// 
			// btnCalculate
			// 
			this->btnCalculate->Location = System::Drawing::Point(184, 32);
			this->btnCalculate->Name = S"btnCalculate";
			this->btnCalculate->TabIndex = 6;
			this->btnCalculate->Text = S"Calculate";
			this->btnCalculate->Click += new System::EventHandler(this, btnCalculate_Click);
			// 
			// txtArea
			// 
			this->txtArea->Location = System::Drawing::Point(96, 96);
			this->txtArea->Name = S"txtArea";
			this->txtArea->Size = System::Drawing::Size(80, 20);
			this->txtArea->TabIndex = 5;
			this->txtArea->Text = S"0.00";
			this->txtArea->TextAlign = System::Windows::Forms::HorizontalAlignment::Right;
			// 
			// txtPerimeter
			// 
			this->txtPerimeter->Location = System::Drawing::Point(96, 64);
			this->txtPerimeter->Name = S"txtPerimeter";
			this->txtPerimeter->Size = System::Drawing::Size(80, 20);
			this->txtPerimeter->TabIndex = 4;
			this->txtPerimeter->Text = S"0.00";
			this->txtPerimeter->TextAlign = System::Windows::Forms::HorizontalAlignment::Right;
			// 
			// txtSide
			// 
			this->txtSide->Location = System::Drawing::Point(96, 32);
			this->txtSide->Name = S"txtSide";
			this->txtSide->Size = System::Drawing::Size(80, 20);
			this->txtSide->TabIndex = 3;
			this->txtSide->Text = S"0.00";
			this->txtSide->TextAlign = System::Windows::Forms::HorizontalAlignment::Right;
			// 
			// label3
			// 
			this->label3->Location = System::Drawing::Point(16, 96);
			this->label3->Name = S"label3";
			this->label3->Size = System::Drawing::Size(80, 23);
			this->label3->TabIndex = 2;
			this->label3->Text = S"Area:";
			// 
			// label2
			// 
			this->label2->Location = System::Drawing::Point(16, 64);
			this->label2->Name = S"label2";
			this->label2->Size = System::Drawing::Size(80, 23);
			this->label2->TabIndex = 1;
			this->label2->Text = S"Perimeter:";
			// 
			// label1
			// 
			this->label1->Location = System::Drawing::Point(16, 32);
			this->label1->Name = S"label1";
			this->label1->Size = System::Drawing::Size(80, 23);
			this->label1->TabIndex = 0;
			this->label1->Text = S"Side:";
			// 
			// Form1
			// 
			this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
			this->ClientSize = System::Drawing::Size(314, 168);
			this->Controls->Add(this->groupBox1);
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog;
			this->MaximizeBox = false;
			this->MinimizeBox = false;
			this->Name = S"Form1";
			this->Text = S"Abstraction";
			this->groupBox1->ResumeLayout(false);
			this->ResumeLayout(false);

		}	
	private: System::Void btnClose_Click(System::Object *  sender, System::EventArgs *  e)
			 {
				 Close();
			 }

private: System::Void btnCalculate_Click(System::Object *  sender, System::EventArgs *  e)
		 {
			 CSquare __gc *Sqr = __gc new CSquare;

			 double s = this->txtSide->Text->ToDouble(0);
			 Sqr->setSide(s);
			 double Perim = Sqr->Perimeter();
			 double Ar    = Sqr->Area();

			 this->txtPerimeter->Text = Perim.ToString();
			 this->txtArea->Text      = Ar.ToString();
		 }
};
}

 

Related Subject

__interface

 

 


Home Copyright © 2004-2010 FunctionX, Inc.