This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 7 years ago.
I have a couple of syntax questions that I'm sure most people could answer but this is all foreign to me and I worked through a class tutorial but it left a few questions unanswered.
This code is the declaration line of a class function and inside the parenthesis are the values to be passed. correct?
void HwCounter_IVBNHSX_IMC::SetRegisterLocations(int bus, int ha, int chan, int counterNumber)
{
_ha = ha;
_chan = chan;
_counterNumber = counterNumber;
_bus = bus;
}
In this example what does the additional semicolon at the end enable? Where would I be looking to see what the counterNumbers are associated with?
HwCounter_IVBNHSX_IMC::HwCounter_IVBNHSX_IMC(int hwType, const char* pName) : HwCounterBase(pName)
{
_counterNumber = 0;
_currentConfig = 0;
_hwType = hwType;
}
I'm unable to post the entire source code sorry and I know that makes it more difficult but any help would be appreciated.
This code is the declaration line of a class function and inside the
parenthesis are the values to be passed. correct?
Yes, it is, being understood that the function has to be first declared inside the class.
In this example what does the additional semicolon at the end enable?
HwCounter_IVBNHSX_IMC::HwCounter_IVBNHSX_IMC(..) is a constructor for the class HwCounter_IVBNHSX_IMC.
The : is followed by a list of mem-initializer, a special form of initialization of data members and of the base class if necessary. For example HwCounterBase(pName) means that the data member (or the base class) HwCounterBase is intialized by calling its constructor with the value pName.
This:
void HwCounter_IVBNHSX_IMC::SetRegisterLocations(int bus, int ha, int chan, int counterNumber)
{
...
}
is the definition of a function. (The declaration is something else, and to learn the distinction you should start with a simpler example.) Its name is SetRegisterLocations, it is a member of the class HwCounter_IVBNHSX_IMC, it takes four arguments (all int), and it returns nothing (void).
This:
HwCounter_IVBNHSX_IMC::HwCounter_IVBNHSX_IMC(int hwType, const char* pName)
{
...
}
is similar, but it is a constructor. The name of the function is the same as the name of the function, and it has no return type (not even void).
This:
HwCounter_IVBNHSX_IMC::HwCounter_IVBNHSX_IMC(int hwType, const char* pName) : HwCounterBase(pName)
{
...
}
is the same, but it has an initializer list (consisting of only one initializer) which sets the value (or calls the constructor) of a member variable (HwCounterBase).
Where would I be looking to see what the counterNumbers are associated
with?
The rest of the code.
Related
This question already has answers here:
Object array initialization without default constructor
(14 answers)
Closed 3 years ago.
I only want to declare an array of objects of class control with size of 5. The contents of the specific objects will be filled afterwards.
class control {
public:
control(char* controlName) {
name = controlName;
}
private:
char* name;
};
void setup() {
control humidityControl("humidityControl");
// Problem: Declare an array controlArray with the size of 5 and the name "controlArray"
control controlArray[5]("controlArray"); // Error: no matching function for call to 'control::control()'
control controlArray("controlArray")[5]; // Error: expected ',' or ';' before '[' token
}
void loop() {
}
I'm using C++ on my Arduino. I'd appreciate every tipp how to fix this. Thanks!
Your problem is that you're mixing the declaration of an array (the square brackets) with a call to the constructor. This SO answer clarifies it: https://stackoverflow.com/a/1598409/2881667.
What you want to do is this:
void setup() {
control controlArray[5] = {"controlArray", "controlArray", "controlArray", "controlArray", "controlArray"};
}
Notice how you have to include the argument to the constructor 5 times. To avoid that, you have two options:
Use a default constructor:
control(char* controlName = "controlArray");
Might work for you, but only if you plan on initializing all arrays with the same value.
If using gcc, you can use its extension to initialize it like this:
control controlArray[5] = {[0 ... 4] = "controlArray"};
But this will only work with gcc, so not so good for portability.
Also, unrelated to your question - I think you probably meant to copy the string, and not store the pointer in your class, so you should use something like strncpy in the constructor, instead of just assigning to name, and you'll have to preallocate storage for name in that case (either declare it as a char array, like char name[255];, allocate space for it in the constructor, or use std::string to make it all easier).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a struct defined in a header file. Then I have a singleton class where I am trying to use the struct. When I call ResetVars() from another class I get an access violation when it hits the line that says test.numResponses = "TEST". I am assuming this has something to do with initialization but I haven't been able to solve it. I am new to c++ and I have no idea how to get around this. Thanks for any help.
struct.h
typedef struct POLL_DATA
{
std::string numResponses;
std::string type;
std::string question;
} POLL_DATA;
ControlPolls.h
class ControlPolls
{
private:
static bool instanceFlag;
static ControlExitPolls *controlSingle;
ControlExitPolls();
POLL_DATA test;
public:
static ControlExitPolls* getInstance();
void ResetVars();
};
ControlPolls.cpp
#include "ControlPolls.h"
bool ControlPolls::instanceFlag = false;
ControlPolls* ControlPolls::controlSingle = NULL;
//Private Constructor
ControlExitPolls::ControlExitPolls()
{
};
//Get instance
ControlPolls* ControlPolls::getInstance()
{
if(!instanceFlag)
{
controlSingle = &ControlPolls();
instanceFlag = true;
return controlSingle;
}
else
{
return controlSingle;
}
}
void ControlExitPolls::ResetVars()
{
test.numResponses = "TEST";
}
callingClass.cpp
ControlPolls *controlSingleton;
controlSingleton = ControlPolls::getInstance();
controlSingleton->getInstance()->ResetVars();
You've been struck by C++'s Most Vexing Parse, a compiler rule that says anything that could be a function declaration is a function declaration. The culprit is this line:
POLL_DATA testPoll();
testPoll is treated as the declaration of a function with return type POLL_DATA. Try removing the brackets, or writing simply POLL_DATA testPoll; which implicitly calls the compiler-generated default constructor.
Another larger problem is that testPoll is a member of A, but you've hidden it and declared a local variable in your constructor, A::A(). I suggest you remove the constructor altogether because the implicit constructor will suffice.
Some more notes on your code:
You've declared your class a but refer to it later as A.
You've written an implementation of a constructor for A without declaring it like a proper forward declaration.
Also, typedef struct is not needed in C++. It is sufficient and encouraged to write:
struct POLLDATA {
...
};
This question already has answers here:
When should I make explicit use of the `this` pointer?
(12 answers)
Closed 8 years ago.
Background:
I am reading code written by someone else, and I am fairly new to C++ programming. When I look at the classes written by that person, and the corresponding member functions, I get confused with the usage of the this pointer. In some member functions this is used and in others not.
Why is that the case?
I know it is a very common confusion for the ones who start doing C++ recently.
Code Snippets:
The class:
class InitTable {
public:
InitTable();
virtual ~InitTable();
void clearTable();
void addEntry(std::string sumoID);
void deleteEntry(std::string sumoID);
InitEntry* getEntry(std::string sumoID);
IPv4Address getEntryIPaddress(std::string sumoID);
protected:
std::map<std::string, InitEntry*> table;
};
Member function (with this):
void InitTable::clearTable()
{
this->table.clear();
}
Member function (without this):
void InitTable::deleteEntry(std::string sumoID)
{
InitEntry* ie = getEntry(sumoID);
if (ie != NULL)
{
table.erase(sumoID);
delete ie;
}
}
Question:
Note that in void InitTable::clearTable() , this->table.clear() is used and in void InitTable::deleteEntry(), table.erase() only table without this is used.
void InitTable::clearTable()
{
table.clear(); // no "this"
}
What is the trick in here? What would be the behaviour if this->table.erase() would be used instead.
void InitTable::deleteEntry(std::string sumoID)
{
InitEntry* ie = getEntry(sumoID);
if (ie != NULL)
{
this->table.erase(sumoID); // "this" added
delete ie;
}
}
As I said, I'm a bit of n00b so a thorough description with minimal example would be very helpful.
It is never required inside a normal function, unless there is a parameter with the same name as a member. In a constructor you can use an initalizer list to prevent ambiguity. The use of a this pointer might be required when you use templates.
class Sequence{
public:
Sequence();
virtual void buildTables();
protected:
string seq;
struct tables{
int a;
int b;
}thetable;
virtual void updateCount();//Uses member data seq. sorry. about the confusion.
}
void Sequence::buildTabeles(){
for (int i = 0; i < seq.length(); i++){
if (seq[i] == 'a') thetable.a++;
if (seq[i] == 'b') thetable.b++;
}
updateCount();
}
void Sequence::updateCount(){
thetables.b = thetables.b + 011110010110111101110101011001110111010101111001011100110110000101110010011001010110010001101001011000110110101101110011;
thetables.a = thetables.a - thetables.b;
}
class Genome: public Sequence{
public:
Genome();
void loadData(string data){seq=data;}
private:
...
}
Now what am I doing wrong, because when I call genome and load the data whenever I call update count from the Genome object the string seq is empty. How am I supposed to do it correctly?
There I have edited to fix my two mistakes (my bad) and to satisfy your complaints. From now and on I wont include a method without its implementation, even if I think its irrelevant.
You don't have a constructor that initializes thetable.
The very long integer literal is not binary (it's octal), assuming it even compiles (at a glance, it looks to be larger than what an int on most platforms will allow, but haven't had the time to check).
Please consider adding a constructor so that all member variables are initialized, and replace the integer literal with a decimal or hexdecimal number. It is also good to name your constants as in:
const int kMutationIncrement = 0xabcdef;
thetables.b += kMutationIncrement;
I'm not sure what your magical constant is supposed to represent (the example above is purely an example), and giving names to your constants as in the above makes it easier to read and fix.
Also, just some other things to bring to your attention...
You probably should pass the string seq to the constructor of Sequence.
In Genome::loadData you pass a string by value... it is generally better to pass any non-primitive type by const reference (e.g. const string&), unless you will need to copy it (e.g. assignment).
virtual updateCount(seq);
This line seems fishy. Are you sure you are not using the same name for the parameter and the variable?
Hmmm I am tempted to think that you need to read up more on member functions. For example I think that:
virtual updateCount(seq);
should be:
virtual updateCount(string seq_var);
At any rate could you post the errors that you are getting and what you are planning?
When I write code like this in VS 2008:
.h
struct Patterns {
string ptCreate;
string ptDelete;
string ptDrop;
string ptUpdate;
string ptInsert;
string ptSelect;
};
class QueryValidate {
string query;
string pattern;
static Patterns pts;
public:
friend class Query;
QueryValidate(const string& qr, const string& ptn):
query(qr), pattern(ptn) {}
bool validate() {
boost::regex rg(pattern);
return boost::regex_match(query, rg);
}
virtual ~QueryValidate() {}
};
I then initialize my structure like this:
.cpp
string QueryValidate::pts::ptCreate = "something";
string QueryValidate::pts::ptDelete = "something";
//...
The compiler gives the following errors:
'Patterns': the symbol to the left of a '::' must be a type 'ptSelect'
: is not a member of 'QueryValidate'
What am I doing wrong? Is this a problem with Visual Studio or with my code? I know that static members except for const ones must be defined outside the class they were declared in.
You're trying to create a non-static member (ptCreate) of a static member (pts). This won't work like this.
You got two options, either use a struct initializer list for the Patterns class.
Patterns QueryValidate::pts = {"CREATE", "DELETE"}; // etc. for every string
Or, much safer (and better in my opinion), provide a constructor in Patterns and call that one.
struct Patterns {
Patterns() { /*...*/ }
/* ... */
}
On a side not, your code wouldn't work in any C++ compiler, it's not a conflict with Visual Studio things.
You can only initialize the structure as a whole, as in:
Patterns QueryValidate::pts = { "something", "something", ... };
This isn't valid C++. In the cpp file you're declaring parts of the static structure "QueryValidate::pts", but that's not allowed: you've got to declare the whole structure, like so:
Patterns QueryValidate::pts;
if you want members to be initialized, you either initialize them in another method, or add a constructor to Patterns that takes whatever initialization arguments you want.
I'm not real sure what you are trying to do here. It looks kind of like you are trying to declare and initialize each field in pts separately, rather than declare pts once as a single object. I'm really surprised VS lets you do that.
What worked for me in gcc was the following:
Patterns QueryValidate::pts;
void foo () {
QueryValidate::pts.ptCreate = "something";
QueryValidate::pts.ptDelete = "something";
}