2011-02-13 112 views
0

我是OOP和C++的新手。C++ ::与所有其他类共享类

我有一个名为数据库的类。这个类的构造函数将建立与数据库的连接。然后,我有其他类,如用户,分数等我希望所有这些类共享从数据库类的连接。我怎么做?

程序流程的示例:

  • 主要功能调用数据库类,它建立与数据库的连接。

  • 我想验证用户,这样的:

    一个用户( “用户1”, “密码1”); a.authenticate(“user1”,“password1”);

但在我的Users :: authenticate函数中,如何利用已建立的连接?

编辑:

我用mysql ++在C++中

阅读的答案后,我会用 “传为基准” 的方法。但我遇到severals错误:

main.cpp 

mysqlpp::Connection conn(false);  

int main() { 
if (conn.connect(DATANAME, HOST, DBUSER, DBPASS)) { 
    Users a(conn, "test","pass"); 
    a.authenticate(); 

这是我的用户构造器和验证功能:

Users.cpp 

Users::Users(mysqlpp::Connection conn, string username, string password) { 
    this->conn = conn; 
    this->username = username; 
    this->password = password; 
} 

void Users::authenticate() { 
    if(this->conn != NULL){ 
     cout << "Have connection" << endl; 
    } else { 
     cout << "No connection" << endl; 
    } 
} 

它可以编译和运行。但它的命令行显示如下:

Segmentation fault. 

任何想法为什么?我猜我的代码有误

+0

即使单例模式将*工作*,我不明白为什么大家都在暗示它。本着给予一点指导的精神,除非你发现其他模式导致了单例的不同问题,否则我不会推荐单例。打开多个数据库连接并不是一个问题(至少,为什么我们会假设它是?),所以单例对一个简单的全局变量static应该没有什么优势。 – tenfour 2011-02-13 12:28:34

回答

5

我建议将连接传递给其他类的构造函数。例如:

Connection conn("servername"); 
User u(conn, "user", "pass"); 

这是其他人建议的静态连接的替代方法。两者都可以正常工作,但是这种模式并没有假设您的应用程序中只有一个数据库连接。

+0

呃,所以COnnection连接(“服务器名称”)是我连接到数据库的线? – 2011-02-13 12:22:21

+0

是的。在概念上,一个`用户`需要构建一些输入 - 用户名和密码以及数据库连接。通过这三个项目,您可以构建一个`User`对象;这就是为什么3个参数给构造函数。 – tenfour 2011-02-13 12:24:06

+0

我明白了。我最后一个问题。我应该在哪里断开连接?在主要功能的结尾? – 2011-02-13 12:27:49

0

可能你应该使用Singleton模式。你可以在四人帮的“设计模式”一书中阅读它。

+0

如果您想要多个连接,该怎么办? – 2011-02-13 12:19:09

+0

例如,您可以创建一个调度程序单例对象,用于存储所有连接并返回相应的连接。 – Kos 2011-02-13 12:22:18

0

声明连接为静态;如果您的数据库类具有Connection对象,则:

static Connection connect; 

您可以通过Database::Connection访问它。

1

您可以将Database对象设为单例 - 请参阅singleton design pattern

这使我想到的第二个解决方案只是给refernece到Database对象构造UsersScores

1

不知怎的,你的用户和得分类会需要与数据库连接信息。有很多方法来完成这一点;这里有一些。

  1. 您可以让每个用户和得分对象在其构造函数中接受一个指向开放数据库对象的指针。这样,他们可以将连接存储起来,以便他们的成员函数可以引用连接。

  2. 您可以将数据库设置为单例,然后让Users和Scores类使用其全局可见连接来读取和写入。这似乎是一个不太理想的设计,因为它会强制程序中的所有对象使用相同的连接。

  3. 您可以让数据库对象导出工厂函数,以使用它的连接创建用户和得分对象。这实质上是第一个想法的变体,它使得类之间的关系更加清晰,并可能简化与其他对象共享私有连接状态变量的逻辑。

  4. 您可以修改用户和成绩的成员函数,以便他们将数据库显式作为参数,允许您根据需要更改数据源。

总之,你有很多选择。选择你认为最适合你的特定应用。

1

不讨论你所描述的设计是否是好还是不好,你whant达到什么是这样的:

class Database 
{ 
public: 
    DbConnection& Connection(); 

private: 
    ... 
}; 

class User 
{ 
public: 
    User(DbConnection& connection) : connection_(connection) { } 

    ... 

    void Authenticate() 
    { 
     ... 
     connection_.Authenticate(username_, password_); 
     ... 
    } 

private: 
    std::wstring username_; 
    std::wstring password_; 
    DbConnection& connection_; 
}