c++ - 重新制定以前的状态 3 查询

标签 c++ scope class-method class-reference

好的,从 C++ Process terminated with status 3 confusion 重新制定和合并使用最少的代码到单个文件,将我的“日志”引用替换为“cout”,打印到控制台而不是文件。我通过 code::blocks 编译器运行它并得到了一个不同的错误,但对于同一行 ['log' 未在此范围内声明]。当我在自己的文件中有这些类时,它只是以“状态 3”关闭程序。

我以前遇到过范围错误,自己修复了它,并认为我理解它,但我想不是......

#include <iostream>
#include <string> // Doesn't complain if this is not present...
using namespace std;

//------------------------------------------------------------
class Logfile {
public:
    bool LACT; // Is log file active?
    string value; // Data to be entered

    Logfile();
    ~Logfile();

    void entry(string value); // Make an entry
};

Logfile::Logfile() { // Constructor
    LACT = true;
    cout << "OPENED\n"; 
}

Logfile::~Logfile() {
    cout << "CLOSED\n";
}

void Logfile::entry(string value) {
    if ( LACT ) cout << value << endl;
}

//--------------------------------------------------
class Engine { // Constructor contains only code for this class right now
public :
    Engine();
};

这一行是编译器挂起并给我错误的地方:

Engine::Engine() {
    log.entry("Engine constructed"); // !Problem line!
}

我认为问题是我错误地从不同类中调用现有对象的类方法是否正确?

//--------------------------------------------------
int main()
{
    Logfile log;
    Engine engine;

    cout << "Hello world!" << endl;

    return 0;
}

当我 '//' 有问题的行时,一切运行正常并且控制台打印出 OPENED, Hello World!, CLOSED。感谢您的耐心和时间,因为我确信这比我看起来要简单得多,而且是新手。

--

我问这个问题的最初目的是(现在我意识到)让一个全局声明的对象可以从多文件程序中的任何 *.cpp 文件访问。我刚找到这个答案:http://www.cplusplus.com/forum/beginner/3848/ ,以防这对遇到类似问题的其他人有所帮助。

最佳答案

logengine 是完全分开的。两者都无法访问对方。

如果您希望 engine 能够访问 Logfile 的实例,您可以通过 setter 或通过 Engine 的构造函数:

Engine::Engine(Logfile& log) {
    log.entry("Engine constructed");
}

还有一些替代方案,您可以在其中拥有 Logfile 的全局实例(在 main 的范围之外)。通常全局变量不是一个好主意;变量的生命周期应该减少到尽可能小的范围。但是,日志文件可能符合此规则的合理异常(exception)情况。


为了进一步解释,您可以为日志文件使用单例。使用单例是一个极具争议的问题。只需搜索单例或双重检查锁定,您就会发现有关危险的大量讨论。

但是,随着 C++11 的出现,事情变得更加安全了。新标准保证局部静态对象的初始化是线程安全的。这使我们可以执行以下操作:

class Logfile {
public:
    static Logfile& instance();
    void entry(const string& value) { cout << value << '\n'; }
private:
    Logfile() { cout << "OPENED\n"; }
    ~Logfile() { cout << "CLOSED\n"; }
};

Logfile& Logfile::instance() {
    static Logfile log_file;
    return log_file;
}

请注意,构造函数现在是私有(private)的。获取 Logfile 的唯一方法是通过 instance() 函数,并且由于它有一个本地静态 Logfile,因此只会有那个例子。

然后您可以在 Engine() 中使用它,例如:

Engine::Engine() {
    Logfile::instance().entry("Engine constructed");
}

不过你还是要小心点。例如,此时VC2012还没有实现C++11要求的局部静态线程安全初始化。

关于c++ - 重新制定以前的状态 3 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13408351/

相关文章:

c++ - 在 native 应用程序中使用 win32

c++ - 将 ML 代码转换为 C++

c++ - 将文件读取到 vector 的 vector ,超出范围错误

javascript - 将 javascript 变量存储在数组中

python - 我们可以在@classmethod 函数中调用用户定义的实例方法吗?

python - classmethod除了把self改成cls还有什么作用?

c++ - 如何更改 CRichEditCtrl 中的突出显示颜色?

r - 在 renderPlot 之外的 Shiny 中为 renderTable 提供一个对象

c++ - 函数用完时结构会归零吗?

objective-c - 差异: Create instances with class methods or by assigning return values to them