CC++Qt « C++ private constructor
в java я писал так:
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .java.geshi_code {font-family:monospace;} .java.geshi_code .imp {font-weight: bold; color: red;} .java.geshi_code .kw1 {color: #000000; font-weight: bold;} .java.geshi_code .kw2 {color: #000066; font-weight: bold;} .java.geshi_code .kw3 {color: #003399;} .java.geshi_code .kw4 {color: #000066; font-weight: bold;} .java.geshi_code .co1 {color: #666666; font-style: italic;} .java.geshi_code .co2 {color: #006699;} .java.geshi_code .co3 {color: #008000; font-style: italic; font-weight: bold;} .java.geshi_code .coMULTI {color: #666666; font-style: italic;} .java.geshi_code .es0 {color: #000099; font-weight: bold;} .java.geshi_code .br0 {color: #009900;} .java.geshi_code .sy0 {color: #339933;} .java.geshi_code .st0 {color: #0000ff;} .java.geshi_code .nu0 {color: #cc66cc;} .java.geshi_code .me1 {color: #006633;} .java.geshi_code .me2 {color: #006633;} .java.geshi_code span.xtra { display:block; }
public class CounterFactory {
private static int count = 0;
private CounterFactory() {}
public static CounterFactory getInstance() {
count ++;
return new CounterFactory();
}
}
т.е конструктор приватный, однако вызываю я его из класса. А с++ приватный конструктор, описанный в .h я вызываю из cpp, на что он ругается.. А как вы работаете с приватными конструкторами?
вот код -
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .cpp.geshi_code {font-family:monospace;} .cpp.geshi_code .imp {font-weight: bold; color: red;} .cpp.geshi_code .kw1 {color: #0000ff;} .cpp.geshi_code .kw2 {color: #0000ff;} .cpp.geshi_code .kw3 {color: #0000dd;} .cpp.geshi_code .kw4 {color: #0000ff;} .cpp.geshi_code .co1 {color: #666666;} .cpp.geshi_code .co2 {color: #339900;} .cpp.geshi_code .coMULTI {color: #ff0000; font-style: italic;} .cpp.geshi_code .es0 {color: #000099; font-weight: bold;} .cpp.geshi_code .es1 {color: #000099; font-weight: bold;} .cpp.geshi_code .es2 {color: #660099; font-weight: bold;} .cpp.geshi_code .es3 {color: #660099; font-weight: bold;} .cpp.geshi_code .es4 {color: #660099; font-weight: bold;} .cpp.geshi_code .es5 {color: #006699; font-weight: bold;} .cpp.geshi_code .br0 {color: #008000;} .cpp.geshi_code .sy0 {color: #008000;} .cpp.geshi_code .sy1 {color: #000080;} .cpp.geshi_code .sy2 {color: #000040;} .cpp.geshi_code .sy3 {color: #000040;} .cpp.geshi_code .sy4 {color: #008080;} .cpp.geshi_code .st0 {color: #FF0000;} .cpp.geshi_code .nu0 {color: #0000dd;} .cpp.geshi_code .nu6 {color: #208080;} .cpp.geshi_code .nu8 {color: #208080;} .cpp.geshi_code .nu12 {color: #208080;} .cpp.geshi_code .nu16 {color:#800080;} .cpp.geshi_code .nu17 {color:#800080;} .cpp.geshi_code .nu18 {color:#800080;} .cpp.geshi_code .nu19 {color:#800080;} .cpp.geshi_code .me1 {color: #007788;} .cpp.geshi_code .me2 {color: #007788;} .cpp.geshi_code span.xtra { display:block; }
#ifndef LOGGER_H
#define LOGGER_H
#include <string>
#include <map>
namespace qwe { namespace util { //namespace qwe::util
class Logger {
public:
typedef Logger* LoggerPtr;
static LoggerPtr getLogger(const std::string& _logger);
void info(const std::string& _msg);
void severe(const std::string& _msg);
void fine(const std::string& _msg);
void warning(const std::string& _msg);
protected:
private:
Logger(const std::string& _name) { loggerName = _name; }
~Logger();
std::string loggerName;
static std::map<std::string, LoggerPtr> loggers;
};
}} // end namespace
#endif
# Logger.cpp --------------------------
#include "../Defines.h" // грабли
#include "Logger.h"
#include <string>
#include <iostream>
#include <map>
using namespace qwe::util;
std::map<std::string, Logger::LoggerPtr> Logger::loggers;
Logger::LoggerPtr Logger::getLogger(const std::string& _logger) {
Logger::LoggerPtr logger = null;
if (loggers[_logger] == null) {
logger = new Logger(_logger);
loggers[_logger] = logger;
} else {
logger = loggers[_logger];
}
return logger;
}
void Logger::fine(const std::string &_msg) {
std::cout << loggerName << " [FINE]: " << _msg << std::endl;
}
void Logger::info(const std::string &_msg) {
std::cout << loggerName << " [INFO]: " << _msg << std::endl;
}
void Logger::warning(const std::string &_msg) {
std::cout << loggerName << " [WARNING]: " << _msg << std::endl;
}
void Logger::severe(const std::string &_msg) {
std::cout << loggerName << " [SEVERE]: " << _msg << std::endl;
}
1 ответов
Попробовал скомпилировать код на VS2008 - все прекрасно работает. Ниже код с незначительными изменениями:
Logger.h
#ifndef LOGGER_H
#define LOGGER_H
#include <string>
#include <map>
namespace qwe { namespace util { //namespace qwe::util
class Logger {
public:
typedef Logger* LoggerPtr;
static LoggerPtr getLogger(const std::string& _logger);
void info(const std::string& _msg);
void severe(const std::string& _msg);
void fine(const std::string& _msg);
void warning(const std::string& _msg);
protected:
private:
Logger(const std::string& _name) { loggerName = _name; }
~Logger();
std::string loggerName;
static std::map<std::string, LoggerPtr> loggers;
};
}} // end namespace
#endif
Logger.cpp
#include "stdafx.h"
#include "logger.h"
#include <string>
#include <iostream>
#include <map>
#define null 0
using namespace qwe::util;
std::map<std::string, Logger::LoggerPtr> Logger::loggers;
Logger::LoggerPtr Logger::getLogger(const std::string& _logger) {
Logger::LoggerPtr logger = null;
if (loggers[_logger] == null) {
logger = new Logger(_logger);
loggers[_logger] = logger;
} else {
logger = loggers[_logger];
}
return logger;
}
void Logger::fine(const std::string &_msg) {
std::cout << loggerName << " [FINE]: " << _msg << std::endl;
}
void Logger::info(const std::string &_msg) {
std::cout << loggerName << " [INFO]: " << _msg << std::endl;
}
void Logger::warning(const std::string &_msg) {
std::cout << loggerName << " [WARNING]: " << _msg << std::endl;
}
void Logger::severe(const std::string &_msg) {
std::cout << loggerName << " [SEVERE]: " << _msg << std::endl;
}
main.cpp
// main.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "logger.h"
using namespace qwe::util;
int _tmain(int argc, _TCHAR* argv[])
{
Logger::LoggerPtr log = Logger::getLogger("test");
return 0;
}
stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
Отличия:
В файле Logger.cpp убрано подключение Defines.h, добавлен макрос #define null 0, добавлено подключение stdafx.h, т.к. создал проект с предкомпилируемыми заголовочными файлами.
Возможно, проблема в файле Defines.h.
При вызове приватного конструктора из статичного метода класса ошибок не возникает. Посмотрите реализацию любого синглтона с "ленивым" вычислением там используется такой же прием.
А можно было бы увидеть твой с++ код? Кстати VS 2008 хвалят её только потому что нету нормальных аналогов и большинство контор использует её. Если хочешь рефакторить и увидеть подчёркивание/выделение и т.д. запиши себе Visual Assist X для студии =)
Точно так же скомпилировал кусок вашего кода, всё отлично работает, скорей всего проблема не в данном куске кода. К тому же, это типичный метод для создания тех же синглтонов. Как уже сказали выше, проверьте "окружение" вашего кода.
Одно замечание, у вас деструктор тоже приватный, но не видно ни единого метода, который призван освобождать память.
Насколько известно мне, нельзя объявлять конструктор приватным и статичным. Деструктор - можно(касательно приватности). А с конструктором не так. Если, опять же, я не ошибаюсь это объясняется например тем, что когда создаешь объект класса, зачастую надо передавать параметр конструктору, в таком случае как должен на это реагировать компилятор? Если отправит ваш параметр - то конструктор перестанет быть приватным, а если нет, то остается выход - игнорировать, что на мой взгляд достойно ошибки, а не варнинга.