# 具有繼承的Singleton，Derived類無法在父實例中實例化？

Mainfile – 1
#include
#include
#include "Singleton.h"
using namespace std;

int main(){

Singleton::instant().print();
cin.get();
}
Singleton.h
#pragma once
#include
using std::cout;
class Singleton{
public:
static Singleton & instant();
virtual void print(){cout<<"Singleton";}
protected:
Singleton(){};
private:
static Singleton * instance_;
Singleton(const Singleton & );
void operator=(const Singleton & );

};

Singleton.cpp
#include "Singleton.h"
#include "Dotted.h"
Singleton * Singleton::instance_ = 0;
Singleton & Singleton::instant(){
if (!instance_)
{
char * style = getenv("STYLE");
if (style){
if (strcmp(style,"dotted")==0)
{
instance_ = new Dotted();
return *instance_;
}           else{
instance_ = new Singleton();
return *instance_;
}
}

else{
instance_ = new Singleton();
return *instance_;
}
}
return *instance_;

}
Dotted.h

#pragma once
class Dotted;

class Dotted:public Singleton{
public:
friend class Singleton;
void print(){cout<<"Dotted";}
private:
Dotted(){};

};


## 最佳答案

• You mean to return type Singleton& or const Singleton&. You are currently returning by value, which is attempting to invoke a copy constructor, and no such constructor exists.
• Your default constructor in Dotted probably is not available in Singleton. I suggest you make Singleton a friend of Dotted so that it is able to access that constructor. Although not 100% sure on this one.
• You forgot to make the function print() virtual, so your override won't manifest itself.
• You have put "friend" in the wrong place; you need to declare Singleton a friend of Dotted in Dotted, not within Singleton.
• You should not make your definition of Singleton::instant inline as it needs to construct an instance of Dotted and, in order to do that, it needs to see Dotted's definition. So you should move that to a source file where it is able to see both Dotted and Singleton's complete definitions, respectively.
• You need to put Singleton* Singleton::instance_ = 0; in a source file somewhere.
• You are missing an else clause in your if(!style) section; currently, if the STYLE environment variable is set, but isn't set to "dotted", then you end up returning a null singleton.

class Printer
{
public:
virtual ~Printer(){}
virtual void print()const = 0
};

class StringPrinter : public Printer
{
public:
StringPrinter() : _str("") {}
StringPrinter(const std::string& str) : _str(str) {}
StringPrinter(const StringPrinter& o) : _str(o._str) {}
virtual ~StringPrinter(){}
virtual void print()const{ std::cout << _str << std::endl; }
StringPrinter& operator=(const StringPrinter& o){ _str = o._str; return *this;}
private:
std::string _str;
};


Then, in any class where you previously used Singleton, simply take a const Printer& object. And print to that object. Elsewhere, you can conditionally construct a StringPrinter("Singleton") or StringPrinter("dotted"). Or possibly some other instance of that interface, although I would suggest using QSettings or some sort of configuration file in place of environment variables, or at least use MYAPPLICATIONNAME_STYLE instead of just STYLE; in other words, if you are going to go the environment variable route, at least qualify its name.