Class Pointer and Virtual Function couldn't be avoided?

Let's look at this simplified code, it gives compilation error
conflicting declaration B m 
at line 34.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;


class A
{
    public:
        void showInfo() { cout << " This is an instance of A" << endl; }
};


class B
{
    public:
        void showInfo() { cout << " This is an instance of B" << endl; }
};


int main()
{
    int selection = 0;

    cout << "Please select '1' or '2' :";
    cin >> selection;


    switch(selection)
    {
        case 1:
            A m;
            break;

        case 2:
            B m;
            break;
    }

    // Below are many functions which are common to A and B ...
    // (just put one here for example)
    m.showInfo();

    return 0;
}


Without using pointer, how to make this works?

Thanks.
Last edited on
If the line 27 to 36 are changed to this:
1
2
    if (selection==1) A m;
    else if (selection==2) B m;


then another compilation error occurs:
error: m was not declared in this scope
at line 40.
Last edited on
One of the ways to make it work is to use class pointer and virtual function, as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
using namespace std;

class Parent
{
    public:
        virtual void showInfo() { }
};

class A : public Parent
{
    public:
        void showInfo() { cout << " This is an instance of A" << endl; }
};


class B : public Parent
{
    public:
        void showInfo() { cout << " This is an instance of B" << endl; }
};


int main()
{
    int selection = 0;

    cout << "Please select '1' or '2' :";
    cin >> selection;

    Parent *m;

    switch(selection)
    {
        case 1:
            m = new A;
            break;

        case 2:
            m = new B;
            break;
    }

    m->showInfo();

    return 0;
}


It works and produces following output:
Please select '1' or '2' :1
 This is an instance of A

Another attempt to run it produce:
Please select '1' or '2' :2
 This is an instance of B


But I try to avoid using pointer. Is there any way?
Thanks.
Last edited on
no there is not. Since if you use a reference, it is constant and would have to be initialized right on declaration.
In all cases above, the reference m does not need to be changed after it is initialized. To be constant is not a problem to m once it is initialized.

The problem is just that, the reference m is declared and initialized within a switch.. case..
Then m become undeclared outside the scope of switch.. case..

In other words, what you mentioned may not be the root of the problem.
If we could find a way to extend the scope of m outside the switch.. case.. , then the problem could be solved.

But, is there any way to extend the scope of m outside the switch.. case.. without using pointer?
Last edited on
No, it is not really possible. All objects need to have a type. An object of type A can't be an object of type B and vice versa.

Instead of using a raw pointer you can use a smart pointer, like std::unique_pointer. The object will be deleted automatically when the smart pointer goes out of scope.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::unique_ptr<Parent> m;

switch(selection)
{
	case 1:
		m.reset(new A);
		break;
	case 2:
		m.reset(new B);
		break;
	default:
		// You will have to handle this case somehow to avoid 
		// that you call functions of m when m is null.
		;
}

m->showInfo();
Last edited on
Thanks for the idea.

Anyway I got compilation error with the std::unique_ptr<Parent> m;

I've included this: #include <memory>

but yet got this error:
error: 'unique_ptr' is not a member of 'std'


I'm using g++ 4.6.3
std::unique_ptr was added in C++11. To enable C++11 features pass -std=c++0x to g++.
Thanks. It works.
Topic archived. No new replies allowed.