0

I have problem with my simple data base program in C++ (with inheritance and virtual func.) I've done class hirarchy which represents the object Weapon:

#ifndef Ammu_h
#define Ammu_h

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

//////////HEADER FILE//////////////
class Weapon{                               
protected:                                      
    string name;
    char damage;

public: 
    virtual void show() = 0;
    //virtual ~Weapon();        
};

class WhiteArm: public Weapon{
protected:
    double sharpness;
    double defence;

};

class Axe: public WhiteArm{
public:
    Axe(string str, char dmg, double shrp, double def){
        name = str;
        damage = dmg;
        sharpness = shrp;
        defence = def;
    };
    void show(){
        cout << this->name << this->damage << this->sharpness << this->defence << endl;
    };

//class Sword: public WhiteArm{...};
//class Club: public WhiteArm{...};

};

#endif

First of all im not quite sure if my implementation is proper.

  1. My main problem is that when I add a virtual destructor, I get error: LNK2001: unresolved external symbol "public: __thiscall Weapon::~Weapon(void)" I thought it is necessary to make the destructor virtual when the base class contains virtual methods.

  2. Is it good to make constructors at the end of hierarchy? (like me, upper)

I will appreciate every suggestion to my code Thanks in advance

jhonkola
  • 3,385
  • 1
  • 17
  • 32
Macieyo
  • 440
  • 6
  • 15

1 Answers1

3

Your virtual destructor still needs to have an implementation, even if you mean for it to be pure virtual. I usually write them using this odd-looking syntax: virtual ~Weapon() = 0 {}.

But that evidently doesn't work with some compilers (all compilers other than Microsoft's?), and rightly so (C++11 draft § 10.4/2):

[ Note: A function declaration cannot provide both a pure-specifier and a definition —end note ] [ Example:

 struct C
 {
    virtual void f() = 0 { }; // ill-formed
 };

Instead, you can either leave out the = 0 or locate the body outside the class definition.

dlf
  • 9,045
  • 4
  • 32
  • 58
  • 1
    @IvanGrynko But having `= 0` prevents you from instantiating the class, even if there are no other pure virtuals in it. It's hard to imagine a scenario where that would be important, but I like to do it anyway just for the sake of rigor. – dlf May 29 '14 at 20:29
  • @dlf Did you try compiling that? I'm pretty sure you must provide an out-of-line definition for a pure virtual function. – Praetorian May 29 '14 at 20:30
  • @Praetorian Yes, and it works. I use this idiom all the time. It looks wrong, but it isn't. The rules for "pure" virtual destructors are weird. – dlf May 29 '14 at 20:30
  • @dlf [Doesn't work for me](http://coliru.stacked-crooked.com/a/c838f81ff5b0e62e) – Praetorian May 29 '14 at 20:32
  • @Praetorian Well apparently I have just learned yet another way in which the Microsoft compiler "improves on" the standard (it will compile that exact code with no complaints). – dlf May 29 '14 at 20:33
  • 1
    @Praetorian, @dlf it's not weird rules. `= 0` means derived classes must provide an implementation, not that the base class can not provide an implementation. So as I'm aware dlf suggested correct way. Another question is that some compilers can't work with it. Maybe some statement from The Holy Standard can fairly judge us. – Ivan May 29 '14 at 20:34
  • Ahh what a shame, indeed I forgot about "{}" and what is worse I was thinking about that half day.. Thank you very much – Macieyo May 29 '14 at 20:36
  • 2
    @IvanGrynko It's not that only some compilers work with it, all of them do. VS seems to have implemented an extension where they allow both pure specifier and definition to be provided together, while §10.4/2 clearly states that's ill-formed. So the correct way to do it is to provide the definition outside the body of the class. – Praetorian May 29 '14 at 20:38
  • @Praetorian, I'm a great believer in C++ Standard, so I'm taking my words back :) Thanks for clarifying this. – Ivan May 29 '14 at 20:52