Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Instantiating classes

Posted on 2013-10-31
11
Medium Priority
?
240 Views
Last Modified: 2013-11-01
I come from a C and C# background. I'm told knowing C# isn't much help in learning C++, as the two are very different.

In C# I would define a class, instantiate some instances, and fill in the data for each instance as needed.
Myclass a = new Myclass;

Open in new window

In C++ I see other ways of instantiating a class:
MyClass* a = new MyClass();

Myclass* a = gcnew Myclass();

Myclass a;

class a : MyClass
{
}

Open in new window

The last one seems like I'm creating a new class definition for a class named a, which inherits MyClass, instead of creating an instance of MyClass. Or, since C++ has multiple inheritance and no "implements interface", is the last one better understood as "creating a new class named a which implements the MyClass interface" (I suppose MyClass would then need to be written as an interface, using pure virtual functions.)

When would I want to use class a : Myclass instead of Myclass a?

I'm also unclear on when to use which:
a.data = 1;
a->data = 1;
a::data = 1;

Open in new window

0
Comment
Question by:deleyd
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 3
  • +1
11 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 39614370
>>When would I want to use class a : Myclass instead of Myclass a?

These are two completely different things - the first one declares a class 'a' that derives from 'Mayclass' (yet syntactically incorrect, while the second expression
instantiates

Open in new window

an instance of 'Myclass'. Think of it like

class Myclass : public Myparent {

public:

  int data1;
  static int data2;
};

Open in new window


Then (to also address the other part) you'd use that like

Myclass a; // instance
Myclass* b = new Myclass; // dynamically created instance

a.data1 = 1; // regular way to access a public data member of an instance
b->data1 = 2; // access a data member of a pointer to a class
Myclass::data2 = 42; // access a static member of a class;

delete b; // clean up the dynamically created instance of 'Myclass' to avoid memory leaks

Open in new window

0
 
LVL 29

Expert Comment

by:pepr
ID: 39614433
In C# (and Java), the Myclass a; is the definition of the variable named a. The variable is actually a reference to the instance. When not assigned it has null value and you cannot reach any object of that class.

In C++, the Myclass a; means creation of the instance of the Myclass. The instance is named a. It is not a reference, it is the object itself. That a will be deleted automatically -- garbage collector not needed. That kind of a class instance is not created using new (this is not possible in C#).

You can also create an object dynamically in C++ using the new -- similarly to C#. However, the operator returns the address of the newly created object. The address can be stored in a pointer variable. The pointer variable should be of the same type. You can declare the variable like this: Myclass* a; and you can possibly initialize it explicitly by assigning the special nullptr value (for newer C++) or NULL (for older C++ standards).

If a is a reference in C#, it is dereferenced automatically -- it behaves as if the a was the object.

If a is a pointer in C++, you must dereference it explicitely via *a or a-->. This way you can write (*a).data or better a-->data. Notice that the star is somehow common to dereferencing and to the pointer type definition. You can also read the Myclass * a; as *a is of Myclass class (the spaces do not matter, writing the star just after the Myclass is only a convention. When working with pointers in C++ the variables are usually prefixed by p (just another convention).

The C++ language knows also references. The variable of the reference type is defined using & (pronounced as ref), and must be initialized when the variable is created. There is nothing like null reference in C++.

If the data is a static member of the class (kind of global for all instances of Myclass), then you can access it without instantiating the class first. Then you use Myclass::data.

Ask for details.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39614470
In C++ I see other ways of instantiating a class
Since no one has mentioned it, I will make the distinction that gcnew is specific to Microsoft's latest version of C++ (the one that can target .NET). gcnew will give you back a handle to an instance that will be garbage collected for you; whereas, new is for unmanaged types (read not-garbage-collected types).

Read up on gcnew for more info:  http://msdn.microsoft.com/en-us/library/te3ecsc8(v=vs.90).aspx
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:deleyd
ID: 39615149
I see the class a : Myclass {} is actually creating a subclass of class Myclass.

I'm studying examples of the State Design Pattern. I'm wondering why are all the states subclasses of a base class, instead of different instances of a base class?

I also note we store the subclass in a variable meant to hold (or point to) an instance of the base class. Doesn't this restrict us to treating the stored class as a base class? Then why store a subclass instead?
0
 
LVL 86

Expert Comment

by:jkr
ID: 39615190
>>I'm wondering why are all the states subclasses of a base class, instead of different
>>instances of a base class?

Because inheritance allows you to diversify the functionality of the base class to suit certain purposes. One (heavily used) graphic and self-explanatory example might be the following:

class Vehicle {

  // basic functionality of a vehicle
public:

  void move();
  void stop();
};

class Car: public Vehicle {

  // extends 'Vehicle' by adding Car-specific functionality
};

class Ship: public Vehicle {

  // extends 'Vehicle' by adding Ship-specific functionality
};

class Submarine: public Boat {

  // extends 'Ship' by adding Submarine-specific functionality
public:
  void submerge();
};

Open in new window

0
 

Author Comment

by:deleyd
ID: 39615357
But if an instance of Submarine is stored in a variable declared to be a Boat, then you can't call submerge, because the Boat class doesn't know about it.
Submarine s = new Submarine();

Boat b;

b = s;
s.submerge();   //OK
b.submerge();   //doesn't work

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 39615421
Yes. A boat cannot submerge, whereas a submarine can. That's the whole point behind that concept ;o)
0
 

Author Comment

by:deleyd
ID: 39615523
But in these State Design Pattern examples, we can't do line 7
Submarine s = new Submarine();

Boat b;

b = s;          //save the current state

b.submerge();   //doesn't work because Boats don't submerge

Open in new window

0
 
LVL 29

Accepted Solution

by:
pepr earned 2000 total points
ID: 39616089
Yes. But both submarine and boat can float on the surface. In the jkr's example, the Boat should actually be named Ship (line 20). Then you can read:

Submarine is a special kind of Ship (or Boat), where Ship is a special kind of Vehicle (the very base class). This way both submarine and Ship share the common method move. This way, you can s.move() but also b.move() in both cases. This is what is important.

To make one step further, in the example there is only a single way to .move(). The more realistic case is when a car, a ship, a submarine move a bit differently. Then the move() method in the base class Vehicle should be declared as virtual. Then each specialized class can redefine the functionality of the move(). But the miracle is that then even the b.move() would execute the Submarine::move() code.
0
 

Author Comment

by:deleyd
ID: 39617546
Then the move() method in the base class Vehicle should be declared as virtual. Then each specialized class can redefine the functionality of the move().
Ah there's the bit I needed to hear! This is how we change the functionality of move().

I was thinking I would need to somehow encapsulate a function into a variable and then set a storage variable to hold that move() function.

I was thinking I'd have to use C++11 std::bind, in something like this:
#include <functional>
#include <string>
#include <iostream>

class MyState {};

class MyStateA : MyState
{
   public:
      MyStateA(std::function<void()> func)
         : func_(func)
      {
      }

      void execute()
      {
         func_();
      }

   private:
      std::function<void()> func_;
};

struct MyStateB : MyState{};

void changeStateTo(MyState const & /* state */)
{
   std::cout << "changeStateTo" << std::endl;
}

float DoStuff(int)
{
   std::cout << "DoStuff" << std::endl;
   return 0.0f;
}

void foobar(int, std::string, float)
{
   std::cout << "foobar" << std::endl;
}

int main()
{
   MyStateA a1(std::bind(changeStateTo, MyStateB()));
   a1.execute();

   MyStateA a2(std::bind(foobar, 12, "a string", DoStuff(5)));
   a2.execute();
}

Open in new window

This gives me the familiar
MyStateA a1;
MyStateA a2;

Open in new window

pattern I was looking for. But perhaps the class extension is a better way to set the functionality of move()?
0
 
LVL 29

Expert Comment

by:pepr
ID: 39618002
You will find here better C++ experts than me. Anyway, I tend to use C++ in rather simplistic way. Your last example seems to me as the atempt to generalize some finite state machine implementation. I cannot tell you what I think about it without knowing details. My experience is that it is better to stick with simpler solutions as you will have to understand it also four years from now. I can bet you will not believe that it was you who wrote the code, and you will appreciate if it is heavily and effectively commented.

My knowledge related to standard templates is really poor. I do not know details of std::bind. Anyway, I suspect that the foobar, DoStuff and the like have no access to the MyStateA and the like classes. This way I see MyStateXYZ classes existence rather artificial way to invoke a function with arguments. But it is likely I only do not understand your intention.

Back to the original .move(). My comment about making it virtual in the base class was rather simplified. Actually, you can also redefine the non-virtual .move() in the derived classes. But then, the objects will not act polymorphically when referenced via their base class. In C++, you want the method virtual, if you have a container of pointers/references of the base type, and you want to use the pointer/reference to call a method specific to the object of some specialized type. I.e. container stores references to the same base type (homogeneous), but the real objects are specialized and they behave differently when a method the same name is called.

The virtual methods are bread-and-butter of the C++ from very beginning. The class definition uses so called virtual table that points to the method-code related to the specialized/base class .
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

670 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question