views:

280

answers:

9

Hi, Let's say I've got class:

class Bad_Date
{
private:
const char* _my_msg;
public:
const char* msg() const
{
return _my_msg;
}
};

And I would like to not be able to create any object of this class but I don't really want to put anything else there and make it pure virtual fnc. Is there any other way to make this class abstract or I have to create dummy fnc and declare it as a pure virtual? Thank you.

+7  A: 

Add pure virtual destructor.

Mykola Golubyev
Thank all of you for your valuable help. Thanks guys.
There is nothing we can do
The downside of this is that it forces you to implement a destructor in every derived class.
sth
@sth, every class has a destructor, that you declare it of not. The compiler provided one is enough to fulfill the requirements caused by a pure destructor in a base class.
AProgrammer
@sth - it's enough to define the dtor in the abstract class (as long as the derived class doen't need any more work done than what's in the base dtor). This can be done even if the dtor is marked as pure virtual.
Michael Burr
You're all right, the automatically generated destructor of a derived class is enough if the base class has a pure virtual destructor with definition.
sth
+1  A: 

You could make the constructor private protected, thus overriding the default constructor:

class Bad_Date
{
    protected:
    Bad_Date() { }
    // rest of the class definition
};
int3
OP never said that it was going to be a base class -- but fine, edited the answer.
int3
The OP might not have explicitly said it'll be used as a base, but what's the use of an abstract class that's not? If not, it's a class that can't be instantiated, so all it can be used for is static members (which aren't in the posted example either).
Michael Burr
+6  A: 

Make the constructor protected:

class Bad_Date
{
private:
const char* _my_msg;

// Add the 2 lines below:
protected:
    Bad_Date() {}

public:
const char* msg() const
{
return _my_msg;
}
};
Polaris878
A: 

My C++ is rusty, but still:

Maybe you can give the class only a private constructor?

IIRC, abstract classes are abstract precisely because they have at least one pure virtual function...

jackrabbit
+9  A: 

If you need a base class, you may need a virtual destructor. Make it pure virtual and you've got your abstract class !

If you don't need a virtual destructor (ie the class is not used polymorphically), you can make the constructor protected (not private).

Samuel_xL
+3  A: 

You can make the destructor pure virtual, and have that be your "dummy function". i.e.

 class Bad_Date
 {
   private:
   const char* _my_msg;
   public:
   const char* msg() const { return _my_msg; }
   virtual ~Bad_Date() = 0;
 };

Making the destructor virtual is a good idea anyway for any class you intend to use polymorphicaly, to ensure that subclass instances get cleaned up appropriately. If you need Bad_Date to do some work in the destructor though, you can't make the destructor pure virtual of course. Making Bad_Date's constructor(s) protected is another viable technique. This will ensure that a Bad_Date can only be constructed by a subclass of Bad_Date. Unfortunately this won't prevent someone from creating a Bad_Date subclass just to act as factory for Bad_Dates.

Beyond that there are compiler specifc extensions for creating abstract base classes, e.g. MSVC has __interface and gcc has used to have signature.

Logan Capaldo
A: 

Make the destructor pure virtual (abstract) - but remember to also give it an implementation, otherwise you'll never be able to destroy objects derived from Bad_Date:

class Bad_Date
{
    // ...

public:  // or maybe protected

    virtual ~Bad_Date() = 0;
};


Bad_Date::~Bad_Date()
{
}

Many people are confused by the combination of pure virtual functions that are also defined, thinking that it makes no sense. But it's not only legal, it's required in some cases (like a pure virtual dtor).

Michael Burr
While you can implement a pure virtual function, you can't do so within the class' definition.
sbi
This isn't syntactically valid C++.
robson3.14
You're both right - that'll teach me to rely on only MSVC as a check. Fixed.
Michael Burr
A: 

You could also make the msg(), pure virtual and also providing it's implementation at the same time. class Bad_Date { private: const char* _my_msg; public: virtual const char* msg() const = 0; };

const char* Bad_Date::msg() const { return _my_msg; }

Rahul Goyal
A: 

You should read this for avoiding common pitfalls with pure virtual destructors.

rmn