Reputation: 152
I am attempting to connect to Sql Server with c++ using sqlapi++. I have gotten my code to work properly in my main function and when I am not instantiating an object within a class, but when I try to move my code over to a separate class I get errors.
The errors I'm getting are:
Expected a type specifier
and
syntax error: '&'
The code that produces the error is:
#include <string>
#include <SQLAPI.h>
class DbConnection
{
SAConnection con;
SACommand cmd(&con); //this line throws the error
public:
int age, id;
void Connect()
{
con.Connect(
"databaseName",
"userName",
"password",
SA_SQLServer_Client);
}
void Retrieve()
{
cmd.setCommandText("SELECT * FROM [dbo].[TableName]");
}
};
When I move the SAConnection
and SACommand
objects outside of the class DbConnection
, the errors go away and it seems to work.
#include <string>
#include <SQLAPI.h>
SAConnection con;
SACommand cmd(&con);
class DbConnection
{
//remaining code
};
I am having a difficult time understanding why that is, coming from other languages where I can instantiate and declare an object inside of a class is normal. I am missing some information, any explanation would be helpful.
Why can I not declare a class inside of another class?
Upvotes: 1
Views: 548
Reputation: 1026
Initializing cmd
in a constructor is an easy way to understand class initialization. Something like this:
class DbConnection
{
SAConnection con;
SACommand cmd; // this is just a declaration
int age;
int id;
public:
// this is the constructor
DbConnection()
: con()
, cmd(&con) // here you initialize it
, age(0)
, id(0)
{
}
...
};
cmd
is a member of your DbConnection
class; its type is SACommand
.
When an instance of the class DbConnection
is constructed, the constructor gets called, and it creates cmd
, an instance of SACommand
. It creates it by calling its constructor and passing it a reference to its SAConnection member: SACommand(&con)
.
EDIT (to answer the question in the comments section):
A class is a way to group, encapsulate, related data and its related operations. In particular, your DbConnection
class encapsulates 4 data members: con, cmd, age and id. It just groups them together. It doesn't inherit them. The constructor is just a member function which job is to initialize the class, and part of initializing the class is to initialize all of its data members by calling their own constructors. Therefore, when you create/instantiate a new DbConnection
class, it internally creates its 4 new data members and initializes them. If you were to create another instance of DbConnection
, it will create its own 4 new internal members, independent of the ones belonging to the first instance of the class.
EDIT #2
As indicated in some of the comments, class data members can be initialized where they are declared since C++11. If you're interested in learning more details, I suggest googling "C++ In-class member initialization." There have been several initialization features on different C++ standards.
Upvotes: 1
Reputation: 1
{
SAConnection con;
SACommand cmd; // this is just a declaration
int age;
int id;
public: //this is the constructor
DbConnection ():con (), cmd (&con), age (0), id (0) // here you initialize it
{
}
//Some Code Here...
};
Upvotes: 0
Reputation: 2235
There is a answer that states that you cannot use class member initalization that is accepted, that is false though. You just need to use braces list insteada of parenthesis. (Its another question if you actually want to use it)
#include <string>
// Dummy code
class SAConnection {};
class SACommand {
public:
SACommand(SAConnection *) {}
};
//
class DbConnection
{
SAConnection con;
SACommand cmd{&con}; // <-- use brace syntax, remember initialization ordering
};
int main() {
}
Upvotes: 1