2010-05-01 105 views
1

我在A.cpp有一个主要的功能,其具有下面的代码相关的两行:C++函数范围

B definition(input_file); 
definition.Print(); 

B.h我有下面的代码相关线路:

class B 
{ 
    public: 
    // Constructors 
    B(void);              
    B(const char *filename); 
    ~B(void); 

    // File input 
    int ParseLSFile(const char *filename); 

    // Debugging 
    void Print(void); 

    // Data 
    int var1; 
    double var2; 
    vector<char* > var3; 
    map<char*, vector<char* > > var4; 
} 

B.cpp ,我有以下功能签名(对不起,因为冗余):

B::B(void) 
    : var1(-1), 
    var2(numeric_limits<double>::infinity()) 
{ 
} 

B::B(const char *filename) 
{ 
    B *def = new B(); 
    def->ParseLSFile(filename); 
} 

B::~B(void) 
{ 
    // Free memory for var3 and var 4 
} 

int B::ParseLSFile(const char *filename) 
{ 
    // assign var1, var2, var3, and var4 values 
} 

void B::Print(void) 
{ 
    // print contents of var1, var2, var3, and var4 to stdout 
} 

因此,当我从B::ParseLSFile(...)中调用Print()时,那么我的结构的内容将正确打印到stdout。但是,当我从A.cpp中调用definition.Print()时,我的结构是空的或包含垃圾。任何人都可以推荐正确的方式来初始化/传递我的结构,以便我可以在我的函数定义范围之外访问它们吗?

谢谢。

+1

无论在你的代码中你有char *,你都应该考虑使用std :: string - 特别是对于地图。 – 2010-05-01 15:30:55

回答

3

而不是使

B *def = new B(); 
def->ParseLSFile(filename); 

在构造函数,你只要简单地写的

ParseLSFile(filename); 

这意味着你的当前对象的成员会用ParseLSFile功能进行初始化。您可以命名该功能InitFromFile以保留一些命名逻辑。

那么你的代码将转变为:

B object_name(filename); 
object_name.Print(); 

和(不完全一样,只是让你了解底层机制)这就像

Create empty object of type B 
Initialize it from file using InitFromFile() 
Call Print() to display the contents of this object 
+0

感谢功能名称的建议。我一直在想一个更好的方式来命名它,我喜欢你的。 – Myx 2010-05-01 16:02:51

2

在你的构造函数,它意味着财产以后一个const char*,您动态创建另一个类的实例并使用该实例而不是当前实例。取而代之的

B *def = new B(); 
def->ParseLSFile(filename); 

你需要就叫

ParseLSFile(filename); 

让您在对象上操作正在兴建。就像现在这样,你有资源泄漏。

在不相干的笔记上,您不应该使用指针作为映射键。就像现在这样,通过它的键来访问一个元素几乎是不可能的,因为只有一个指针比较会被完成;不会比较char*指向的字符串值。您应该使用std::string作为键类型。