C ++ :: Поделиться классом со всеми другими классами - PullRequest
0 голосов
/ 13 февраля 2011

Я новичок в ООП и C ++.

У меня есть класс под названием База данных. Конструктор этого класса установит соединение с базой данных. Затем у меня есть другие классы, такие как Users, Scores и т. Д. Я хочу, чтобы все эти классы совместно использовали соединение из класса Database. Как мне это сделать?

Пример выполнения программы:

  • Основная функция, называемая классом базы данных, которая устанавливает соединение с базой данных.

  • Я хочу аутентифицировать пользователя, например:

    Users a ("user1", "password1"); a.authenticate ("user1", "password1");

Но в моей функции Users :: authenticate, как использовать соединение, которое уже установлено ??

EDIT:

Я использую MySQL в C ++

После прочтения ответа я буду использовать метод «передать как ссылку». Но я столкнулся с несколькими ошибками:

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.

Есть идеи, почему? Я думаю, мой код неверен

Ответы [ 8 ]

5 голосов
/ 13 февраля 2011

Я бы предложил передать связь с конструкторами других классов.Например:

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

Это альтернатива статическому соединению, которое предлагают другие.Оба работают нормально, но этот шаблон не предполагает, что в вашем запущенном приложении есть только одно соединение с базой данных.

1 голос
/ 13 февраля 2011

Не обсуждая, хорош ли описанный вами дизайн или нет, вам нужно достичь следующего:

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_;
}
1 голос
/ 13 февраля 2011

Каким-то образом вашим классам Users и Scores потребуется информация о подключении к базе данных.Есть много способов сделать это;Вот некоторые из них.

  1. Каждый объект Users и Scores может иметь указатель на открытый объект Database в своих конструкторах.Таким образом, они могут сохранить соединение для дальнейшего использования, а их функции-члены могут ссылаться на соединение.

  2. Вы можете сделать базу данных одиночной, а затем классы Users и Scores использовать ее глобально.видимая связь для чтения и записи.Это выглядит как неоптимальный дизайн, потому что он заставляет все объекты в программе использовать одно и то же соединение.

  3. Можно создать функции фабрики экспорта объектов базы данных для создания объектов Users и Scores.используя это соединение.По сути, это вариант первой идеи, который делает отношения между классами более четкими и может упростить логику для совместного использования переменных состояния частного соединения с другими объектами.

  4. Вы можете изменитьфункции-члены Users и Scores, так что они явно принимают базу данных в качестве аргумента, что позволяет вам изменять источник данных по своему усмотрению.

Короче говоря, у вас есть многовариантов.Выберите то, что вы считаете лучшим для вашего конкретного применения.

1 голос
/ 13 февраля 2011

Вы можете сделать Database объект одноэлементным - см. одноэлементный шаблон проектирования .

Второе решение, которое приходит мне в голову, - просто дать ссылку на объект Database в конструкторе Users, Scores и т. Д.

0 голосов
/ 13 февраля 2011

Один из способов сделать это - сделать класс базы данных одноэлементным.Однако практика TDD говорит, что вы должны передавать класс базы данных любому классу, который должен его использовать.

См. Здесь пример Singleton http://www.codeproject.com/KB/cpp/singletonrvs.aspx

0 голосов
/ 13 февраля 2011

Объявить соединение как статическое; если у вашего класса Database есть объект Connection, тогда:

static Connection connect;

Вы можете получить к нему доступ через Database::Connection.

0 голосов
/ 13 февраля 2011

Вероятно, вы должны использовать шаблон Singleton для этого.Вы можете прочитать об этом в книге «Дизайнерские узоры» Банды Четырех.

0 голосов
/ 13 февраля 2011

Вы можете использовать статическую переменную. http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx

Таким образом, вы можете получить доступ к одному и тому же значению из разных классов.

...