Copy Constructors & Abstract Classes

Hey all -

Hoping you could help me understand something about copy constructors - specifically how to declare them.

Lets say you have an abstract class with private data.Whose private data is a name that can be accessed by a getColor() function.

Lets call this class A.

Now lets assume you have a inherited class that inherits from class A, lets call it class B. Class B also has a type.

Class B gets its name from Class A but does not have a name of its own - thus how does one accomplish a copy constructor for either class?

I know C++ will make the copy construct, ==operator and destructor automatically. (In most cases this is ok).

How does one do this manually however?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef A_H
#define A_H

#include <iostream>
#include <cstring>
using namespace std;

class A {

public:
    A(string color);
    virtual ~A();
    A(const A& other);
    A& operator=(const A& rhs);

    virtual void getColor() =0;

private:
    string _color;

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef B_H
#define B_H

#include <iostream>
#include <cstring>
using namespace std;

class B : public A {

public:
    B(string color, string type);
    virtual ~B();
    B(const B& other);
    B& operator=(const B& rhs);

    virtual void getColor() = 0;

private:
    string _type;

#endif


If those are the headers - how would I setup the cpp files?

With initializer lists:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
A::A(string color)
  : _color(color)
{}

//...

A::A(const A& other)
  : _color(other.color)
{}

//...

B::B(string color, string type)
  : A(color)
  , _type(type)
{}

B::B(const B& other)
  : A(other)
  , _type(other.type)
{}

First off, using namespace std; has no place in a header. You'd inject the entire std namespace into any compilation unit that directly or indirectly includes your header, whether the user wants it or not. That is not acceptable.
The header for std::string is called string, not cstring, by the way.

RC325 wrote:
Class B gets its name from Class A but does not have a name of its own

I assume you mean "color", not "name"?

Anyway, I guess I'll just demonstrate:

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
48
49
50
51
52
#ifndef A_H
#define A_H

#include <iostream>
#include <string>

class A
{
  public:
    A(const std::string& color) : color(color) {}
    virtual ~A() {}
    A(const A& src) : color(src.color) {}
    A& operator=(const A& rhs)
    {
      color=rhs.color;
      return *this;
    }

    virtual void getColor()=0;

  private:
    std::string color;
};

#endif

#ifndef B_H
#define B_H

#include <iostream>
#include <string>

class B : public A
{
  public:
    B(const std::string& color,const std::string& type) : A(color), type(type) {}
    virtual ~B() {}
    B(const B& src) : A(src), type(src.type) {}
    B& operator=(const B& rhs)
    {
      A::operator=(rhs);
      type=rhs.type;
      return *this;
    }

    virtual void getColor()=0;

  private:
    std::string type;
};

#endif 


A note: unless you have specific and good reasons against it, implementations of frequently used, short functions belong into the header. That especially goes for the copy constructor, other constructors and destructors (twice so if it doesn't even do anything).
Disch -

If the data you are trying to copy is private...?
Athar I am considering your reply.

Looks very informative. Thank you.

RC325
If the data you are trying to copy is private...?


I don't understand the question.

The examples I posted will work with the example you posted. Each class appropriately constructs its own memers, so it's irrelevent if the members are private.


Athar's response goes into a bit more detail, so whatever. =P
When I use one of your examples as a template for the classes I am trying to write I keep on getting an error saying that the data is not a member.

Thanks Disch,
RC325
Topic archived. No new replies allowed.