const std::string argument propagation failure in constructor

162 views Asked by At

I am learning to use the Wt (witty) C++ Library, and tried to improvise on the Dbo::Session with singleton. The following is a snippet from the MySQL Backend Singleton wrapper that I had created.

Failure Case

The program compiles and runs with an exception : MySQL Connect Failure.

On debugging with GDB it revealed that the value of the var dbhost at //BREAKPOINT was "localhost" however, at //STEP1 the value was garbage.

Observations

Wt::Dbo API peculiarly shows that the MySQL class constructor has only one string argument that is not passed by reference const std::string dbhost. The function signature from the header file is

MySQL(const std::string &db, const std::string &dbuser="root",
      const std::string &dbpasswd="", const std::string dbhost="localhost",
      unsigned int dbport = 0,
      const std::string &dbsocket ="/var/run/mysqld/mysqld.sock",
      int fractionalSecondsPart = -1);

Success Case

The same code with only three arguments passed to the super class constructor

MySQL(db, dbuser, dbpasswd) // like this

returns the desired mysql backend object to the code.

Help is solicited in understanding the behaviour and solving the problem.

Following is the code used for compilation

#ifndef CANDBM_MODEL_MYSQL_SINGLETON_H
#define CANDBM_MODEL_MYSQL_SINGLETON_H

#include <Wt/Dbo/Dbo>
#include <Wt/Dbo/backend/MySQL>

namespace dbo = Wt::Dbo;

namespace Candbm { namespace Model {

    class MysqlSingleton : public dbo::backend::MySQL
    {
    private:

      static std::string const DB_NAME;
      static std::string const DB_USER;
      static std::string const DB_PASS;
      static std::string const DB_HOST;
      static int const DB_PORT;

      static MysqlSingleton* mysql;

      MysqlSingleton(
                     const std::string& db,
                     const std::string& dbuser = "root",
                     const std::string& dbpass = "",
                     const std::string dbhost = "localhost",
                     unsigned int dbport = 0,
                     const std::string& dbsocket = "/var/run/msyqld/mysqld.sock",
                     int fractionalSecondsPart = -1
                     )
        : MySQL(db, dbuser, dbpass, dbhost, dbport, dbsocket, // STEP 1
                fractionalSecondsPart
                ) {}
      MysqlSingleton(MysqlSingleton const& m) : dbo::backend::MySQL(m) {}
      MysqlSingleton operator=(MysqlSingleton const&);

    public:
      static MysqlSingleton* getBackend() { return instance(); }
      static MysqlSingleton* instance();
    };

    std::string const MysqlSingleton::DB_NAME = "wt_candbm";
    std::string const MysqlSingleton::DB_USER = "wtcandbm";
    std::string const MysqlSingleton::DB_PASS = "somedummyvalue";
    std::string const MysqlSingleton::DB_HOST = "localhost";
    int const MysqlSingleton::DB_PORT = 0;
    MysqlSingleton* MysqlSingleton::mysql = NULL;

    MysqlSingleton* MysqlSingleton::instance()
    {
      if (!mysql)
        { // BREAKPOINT 1
          // EDIT 1: commented the following line
          // static std::string dbhost(DB_HOST.begin(), DB_HOST.end());
          // EDIT 2: the constant directly passed here ,,,,,,,
          mysql = new MysqlSingleton(DB_NAME, DB_USER, DB_PASS, DB_HOST, DB_PORT);
          mysql->setProperty("show-queries", "true");
        }
      return mysql;
    }

  } }

#endif

Updates:

  1. EDIT 1:2: The two edits do simplify the code as suggested by @dma. And now the garbage is obtained in the next constructor invocation. i.e. Next step in debugger in the file MySQL.C
0

There are 0 answers