C++ 向量成员已重置且不可访问

C++ 向量成员已重置且不可访问,c++,pointers,vector,forward-declaration,C++,Pointers,Vector,Forward Declaration,我有两个项目,一个基本客户端和一个动态库。 以下是客户端中发生的情况: int main() { Scrutinizer scru; scru.Scrutinize(); return 0; } 在DLL中,监查器类是这样的(uu declspec(dllexport),为了清楚起见,省略了这样的类) 标题 class ProcessesGenerator; class Scrutinizer { public: Scrutinizer

我有两个项目,一个基本客户端和一个动态库。 以下是客户端中发生的情况:

int main()
{
    Scrutinizer scru;
    scru.Scrutinize();
    return 0;
}
在DLL中,
监查器
类是这样的(uu declspec(dllexport),为了清楚起见,省略了这样的类)

标题

class ProcessesGenerator;

    class Scrutinizer
    {
    public:
    Scrutinizer();
    ~Scrutinizer();
    ProcessesGenerator *ProcGenerator
    void Scrutinize();
};
class ProcessesGenerator
{

public:
    ProcessesGenerator();
    ~ProcessesGenerator();
    WinFinder winFinder;
    std::vector<std::string> fooCollec;

    void GenerateProcesses();
};
ProcessesGenerator
的转发声明对我来说是“强制性的”,以避免某种循环引用

.cpp文件中的构造函数

以下是我如何初始化它:

Scrutinizer::Scrutinizer()
{
    ProcGenerator = &ProcessesGenerator();
}
有关此
ProcessesGenerator
类的详细信息:

标题

class ProcessesGenerator;

    class Scrutinizer
    {
    public:
    Scrutinizer();
    ~Scrutinizer();
    ProcessesGenerator *ProcGenerator
    void Scrutinize();
};
class ProcessesGenerator
{

public:
    ProcessesGenerator();
    ~ProcessesGenerator();
    WinFinder winFinder;
    std::vector<std::string> fooCollec;

    void GenerateProcesses();
};
类进程生成器
{
公众:
进程生成器();
~ProcessesGenerator();
WinFinder WinFinder;
std::向量foocolec;
无效生成过程();
};
进程生成器.cpp

建造商:

ProcessesGenerator::ProcessesGenerator()
{
    //winFinder = WinFinder();//problem will be the same with or without this line
    fooCollec = std::vector<std::string>{"one", "two", "three"};
}
ProcessesGenerator::ProcessesGenerator()
{
//winFinder=winFinder();//无论是否使用此行,问题都是一样的
foocolec=std::向量{“一”、“二”、“三”};
}
构造函数中的断点显示向量已使用所选值初始化

有问题的功能:

void ProcessesGenerator::GenerateProcesses() {
    std::string foo = "bar";
    fooCollec = std::vector<std::string>{};//read access violation
    fooCollec.push_back(foo);//read access violation
    winFinder.SomeVector= std::vector<std::string>{};//read access violation
}
void ProcessesGenerator::generateProcess(){
std::string foo=“bar”;
foocolec=std::vector{};//读取访问冲突
foocolec.push_back(foo);//读取访问冲突
winFinder.SomeVector=std::vector{};//读取访问冲突
}
在那里,我可以看到向量的大小被重置为0。任何重新初始化它或推送元素的尝试都会导致读访问冲突。其
WinFinder
成员的vecotr成员也是如此。我想缺陷很明显,但我真的不明白

谢谢

你的问题在于

Scrutinizer::Scrutinizer()
{
    ProcGenerator = &ProcessesGenerator();
}
您所做的是获取临时对象的地址。该对象将被销毁,在该行的末尾,您将得到一个不指向有效对象的指针

修复它的旧方法是使用

Scrutinizer::Scrutinizer()
{
    ProcGenerator = new ProcessesGenerator();
}
但是现在必须实现复制构造函数、复制赋值操作符和析构函数。既然你有一个现代的编译器,你可以做的就是把
ProcGenerator
a
std:unique\u ptr
变成
scruinizer()

Scrutinizer::Scrutinizer() : ProcGenerator(make_unique<ProcessesGenerator>()) {}
scrutnizer::scrutnizer():ProcGenerator(使_唯一()){

我还想添加
&ProcessesGenerator()甚至不应该编译。不幸的是,MSVS有一个非标准的扩展,允许进行编译。您可以打开
/Za
编译器选项(强制ANSI兼容性),然后会出现如下错误

错误C2102:“&”需要l值

你的问题在于

Scrutinizer::Scrutinizer()
{
    ProcGenerator = &ProcessesGenerator();
}
您所做的是获取临时对象的地址。该对象将被销毁,在该行的末尾,您将得到一个不指向有效对象的指针

修复它的旧方法是使用

Scrutinizer::Scrutinizer()
{
    ProcGenerator = new ProcessesGenerator();
}
但是现在必须实现复制构造函数、复制赋值操作符和析构函数。既然你有一个现代的编译器,你可以做的就是把
ProcGenerator
a
std:unique\u ptr
变成
scruinizer()

Scrutinizer::Scrutinizer() : ProcGenerator(make_unique<ProcessesGenerator>()) {}
scrutnizer::scrutnizer():ProcGenerator(使_唯一()){

我还想添加
&ProcessesGenerator()甚至不应该编译。不幸的是,MSVS有一个非标准的扩展,允许进行编译。您可以打开
/Za
编译器选项(强制ANSI兼容性),然后会出现如下错误

错误C2102:“&”需要l值


ProcGenerator=&ProcessesGenerator()
生成一个临时的
ProcessesGenerator
,获取其地址,然后将其放入
ProcGenerator
指针中。然后,临时材料被销毁,留下垃圾


您可能希望在堆
ProcGenerator=newprocessesGenerator上分配它
但即使在这种情况下,我也强烈建议使用
unique\u ptr
而不是原始指针。

ProcGenerator=&ProcessesGenerator()
生成一个临时的
ProcessesGenerator
,获取其地址,然后将其放入
ProcGenerator
指针中。然后,临时材料被销毁,留下垃圾


您可能希望在堆
ProcGenerator=newprocessesGenerator上分配它
但即使在这种情况下,我也强烈建议使用
unique\u ptr
而不是原始指针。

您使用的编译器是什么<代码>ProcGenerator=&ProcessesGenerator()不应编译。我在Windows 10下的Visual Studio 2017上,通过“构建”函数或单击“本地Windows调试器”@NathanOliver(这是众所周知的讨厌的MS功能)-temp to Levalue implicit来编译它conversion@Slava那只是犯罪。这和将临时变量绑定到非常量引用一样糟糕。你在使用什么编译器<代码>ProcGenerator=&ProcessesGenerator()不应编译。我在Windows 10下的Visual Studio 2017上,通过“构建”函数或单击“本地Windows调试器”@NathanOliver(这是众所周知的讨厌的MS功能)-temp to Levalue implicit来编译它conversion@Slava那只是犯罪。这和他们把临时表和非常量引用绑定一样糟糕。非常感谢你花时间来帮助和教学!它在一个最小的项目上工作,但我的实际项目向我展示了让我首先使用转发声明的奇怪错误。几个小时后我无法修复它,所以我没有让它成为类的成员,并在需要时创建一个新实例。我猜从C到C++的Goig不会这么快发生…谢谢你,谢谢你花时间帮助和指导!它在一个最小的项目上工作,但我的实际项目向我展示了让我首先使用转发声明的奇怪错误。