I am trying to have a declaration of 2d array in private part of my class and then latter on, the functions of this class will use and modify the values in the array, but I am getting an error which says "I-value specified const object". What is wrong with this code and how can I fix it?
Here is a simple code demonstrating my problem
in someClass.h________________
class someClass
{
public:
//Some code here
private:
char grid[20][20];
//Some code here
}
in someClass.cpp______________
lets say one of the functions is trying to reassign the value of item in position (0,0) like so.
grid[0][0]='*';
This gives me an error saying, expression must be modifiable lvalue.
Move it from private to public so you can access it outside the class. If it is private then only functions inside the class can use it.
Related
I'm new to C++ and trying to figure this out. When I compile, I get the error a nonstatic member reference must be relative to a specific object. What's the correct way of writing the code? This is what I have where numShapes is giving me the error.
class Application
private:
int numShapes;
public:
Shapes * shapes[numShapes];
I then have this in another header as my virtual base class, if that's the correct term.
class Shapes
{
virtual void draw(char letter);
virtual ~Shapes() {}
};
The code Shapes * shapes[numShapes]; is requesting the compiler to reserve numShapes amount of space. The problem is that it does not have a known value at compile time. So either make numshapes a constant, or look into dynamic memory allocation.
Instead of
Shapes * shapes[numShapes];
I suggest the use of:
std::vector<Shapes*> shapes;
Remove numShapes altogether since you can get the size from shapes.
Initialize shapes in the constructor. Something along the lines of the following should work.
Application::Application(std::size_t numShapes) : shapes(numShapes, nullptr) {}
I am learning some C++ but obviously my brain is still in Java-Mode.
I try to increment an integer variable which is a class variable of another class, to which I have got a pointer as member variable in my active class.
So the basic structure:
class A{
public:
int i=0;
}
class B{
public:
A* a;
void incrementA();
}
void incrementA(){
a->i=a->i+1;
}
For some reason it still returns 0, while:
a->i=1;
returns 1.
Is there some kind of mechanism that prevents me from accessing variables via pointers?
void incrementA(){
a->i=a->i+1;
}
this function doesnt belong to class B
you are just defining a standalone function, thats now how you define a member function outside the class.
you should define it like this:
void B::incrementA()
{
//body
}
while a->i=1; returns 1.
that is because you are assigning it to 1
the implementation of your incrementA is correct in both semantic and syntax.
`a->i+=1;`
will also do.
To fix this:
the creator of thread said:
Hey everyone, sorry for bothering you, i finally found the problem: In the destructor of B i decrement a->i, and I didnt know that emplace_back() uses the destructor to remove the buffered object :(
I have searched through some SO articles but haven't found anything (yet) that quite addresses my question. Apologies if this answer does already exist somewhere.
A bit of background first...
I want to represent a device with "sections" of functionality, where the functionality has a hierarchical tree-like structure. Rather than have a load of flattened functions like
DeviceReferenceCheck(),
DeviceRefereceSet(),
DevicePhaseSetX(),
DevicePhaseDefaultsSet...()
I'd instead like to leverage nested classes so I could get
dev.reference.check()
dev.reference.set()
dev.phase.setx()
dev.phase.defaults.set...()
To do this I'm trying to use nested classes to get the obj.func.subfunction.subsub....() structure. The nested classes need a reference to the outermost class because they need to use read/write functions provided there.
In my attempts, the first thing I don't understand very well is as follows... I had tried this myself but then stopped using it because of a compiler warning.
class GPIBDevice_Agilent53132A : public GPIBDevice
{
private:
class RefOsc {
public:
// ... snip ...
RefOsc(GPIBDevice_Agilent53132A &parent);
// ... snip ...
} ro;
public:
// ... snip ...
GPIBDevice_Agilent53132A();
// ... snip ...
};
GPIBDevice_Agilent53132A::GPIBDevice_Agilent53132A() : GPIBDevice(), ro(*this)
{
}
Compiler says: gpibdevice_agilent53132a.cpp(5): warning C4355: 'this' : used in base member initializer list.
Aha, I think to myself... clever compiler... using this in the initialiser list is probably not a good idea because the class hasn't been fully constructed yet.
Question 1:
Is what I've said above correct? Is using this, in the enclosing class' initialiser list, to give the nested class a reference to the enclosing class, a bad idea? My thoughts are "yes" but would like some clarification because in other SO threads I have seen this method being used (Nested Class member function can't access function of enclosing class. Why?).
My approach to get around this was to have a member pointer to nested and then when actually in the constructor (so now safe to use this as class has been constructed) made a new inner class where I could pass in the reference to *this without warnings. Is this the standard way of doing it?
Continuing on....
The reason for the private nested class is btw that I don't want the user to be able to instantiate that class him/herself. Now, I did have it public to begin with... tried to use a private constructor in the nested class, but then the compiler told me it couldn't construct the class. So presumably the enclosing class can see nested class private data members?
Question 2:
Why can't the enclosing class see the nested classes private data members/functions?
My work around for this is to have the nested class declare the enclosing class as a friend. Is this really necessary?
Thanks for you help guys!
Summary
Thanks to Jan for his explanation of the curiously recurring template pattern. It's an interesting method to know about.
I've ended up accepting my own answer because I feel it answers the questions directly. The CRTP method is good but doesn't directly answer questions 1 & 2, but does provide a good alternative.
Question 1:
It would seem that this is possible. Thank you to mkirci and R. Martinho Fernandes for confirming my suspicions on why the compiler generated the warning and whether it was "safe" to ignore it.
In summary... not the best idea to use this in the initialiser list of the constructor because the class has not yet been constructed. As the guys point out, this can cause UB if the pointer is used. I've decided to use my work around which is use a pointer to the inner class, and then create it once inside the outer-class constructor... this way outer class is already created and can pass a reference to itself to the inner class safely.
Question 2:
From the C++ standard, I have found (after a lot of digging) in section 11.7:
A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules (Clause 11) shall be obeyed.
The standard gave the following example:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
int g(I* p) {
return p->y; // error: I::y is private
}
};
So, this is (annoyingly) why my outer class cannot call the inner class' private constructor. My solution has been to make the outer class a friend of the inner class. I.e in the above example add friend E; into the inner class decl.
I am working on a small project in C++ that requires me to create an object of a custom class I wrote in another one of my classes. The class is called FIRFilterModule, It has a simple blank constructor.
Being of a java background, my impulse is to create it like this:
class SensorInput{
public:
FIRFilterModule firFilter;
...More Class Members...
SensorInput():firFilter(FIRFilterModule()){}
...};
However this compiles with the ever so helpful error message of "Error within this context". I'm a little lost why that doesn't work. Increasing my confusion I changed the code to this:
class SensorInput{
public:
FIRFilterModule firFilter;
...More Class Members...
SensorInput(){}
...};
It works.
Can someone help me understand why this is so?
In this particular case, running of the default constructor for a member field, you don't have to do anything. The constructor is run automatically. So you can just write
class SensorInput{
public:
FIRFilterModule firFilter;
SensorInput() { ... }
};
The member initialization list is only needed when you need to call a constructor which has arguments or initialize POD types. For example say the FIRFilterModule had a constructor which took an int. Then you would use the memeber initialization list
SensorInput() : firFilter(42) { ... }
The code you posted is correct.
Maybe you forgot to include the header where FIRFilterModule is declared.
Otherwise, everything should work.
Is the following code legal in C++. Accessing a friend class member public method? I know this sounds confusing, and the best way to show it is in code. I was wondering if the TestClassC::Method() is valid in the code below?
I've compiled (g++) and it works, however, I run into a situation, where it produces a segmentation fault on other machine/distros at TestClassC::Method(). Which is making me wonder if this->classA_Ptr->classB.Method(); is legal in C++.
#include <iostream>
using namespace std;
class TestClassB
{
public:
TestClassB(void){};
~TestClassB(void){};
void Method(void){
cout << "Hello Again" << endl;
}
};
class TestClassC; //Forward Declaration
class TestClassA
{
friend class TestClassC;
public:
TestClassA(void){};
~TestClassA(void){};
private:
TestClassB classB;
};
class TestClassC
{
public:
TestClassC(TestClassA* a_Ptr){
this->classA_Ptr = a_Ptr;
}
~TestClassC(void){};
void Method(void){
//Is this Valid/Legal ???
this->classA_Ptr->classB.Method();
}
private:
TestClassA* classA_Ptr;
};
int main()
{
cout << "Hello world!" << endl;
TestClassA testClassA;
TestClassC classC(&testClassA);
classC.Method();
return 0;
}
The public/private/protected accessor modifiers are enforced at compile-time, not at runtime. The SEGFAULT is a runtime error, not a compile-time error. So, in the future, if you get a SEGFAULT, you can be sure that it is not related to the level of access. It sounds like your confusion is based on whether the access modifiers are applied directly, indirectly, transitively, etc. The access modifiers work in the most simple and straight-forward way: they apply only directly, to the functions or variables that have been declared in that class and control access through the given class to those items. Once you have access to such an item, further access is determined purely by that item's own access modifiers.
A SEGFAULT is typically indicative of an illegal memory access. If you experience SEGFAULTS, look at where you dereference pointers (whenever you have *X or X->Y). Common causes of SEGFAULTS include dereferencing NULL, off-by-one array access, and using an object through a pointer where the object in question has already been deleted by going out of scope.
Yes. The friend specification gives TestClassC access to any protected or private members of TestClassA. So that means it gets access to the classB member. After that, normal rules apply to what TestClassC can do with that member. And since Method() is public TestClassC is allowed to call it, just as if it had gotten ahold of a TestClassB instance through any other means.
Regarding the seg fault:
Public/protected/private/friend are all compile-time restrictions. They should have no affect on the operation of the code at runtime.
Is it this exact code that seg faults? Or is it just something similar in concept? If it's not the exact same code, then have you verified that all the pointers are actually valid in the problematic code?
Calling public methods of any class is valid/legal as long as the class is unambiguously accessible, and we have a valid object expression to access it. In fact that's why it was made public in the first place. Your code looks to be fine to me.