CList's AddTail() assertion error - mfc

I was trying to create a double-dimensional List in MFC in order to save and work with some int and CString data. So, I've tried something like this:
#include "A.h"
//A.cpp
A::A()
{
}
A::~A()
{
}
//**********************
#pragma once
// A.h
class A: public CObject
{
public:
A();
virtual ~A();
int ID;
CString label;
};
//**********************
#include "A.h"
#pragma once
// B.h
class B : public CObject
{
public:
B();
virtual ~B();
int anotherID;
CString anotherLabel;
CList<A*, A*&> * AList;
CList<CString, CString&> * TestList;
};
//Note: B.cpp is pretty much the same as A.cpp
//*********************
//C.cpp
void C::Foo()
{
B * b = new B;
A * a = new A;
a->ID = 1;
a->label = L"something";
b->AList->AddTail(a); //Assertion error!
CString aux = L"another thing";
b->TestList->AddTail(aux); //Assertion error!
}
Here's the problem: when I try to use the AddList() method, I receive the error "Access violation reading location". I first thought that the problem was related to the CObject derived classes, but I am not sure if this is the real problem. I've also tried to do some new and delete overloading, but the problem became even worst.
Any ideas?

Both the list elements are declared as pointers, so you'll need to either allocate them or declare them as
CList<A*, A*&> AList; // without the "*"
CList<CString, CString&> TestList; // without the "*"

Related

How do I initialize a dynamically allocated array within a class constructor

we are supposed to assign an empty string into each index and later replace
that with a value in the function addB().
I am quite new to this so I am having a lot of trouble.
class A //in a.h
{
private:
B * b;
int maxNumberOfItems;
//...
public:
A();
~A();
void addB(const B & something);
};
//in a.cpp
A::A()
{
maxNumberOfItems=10;
for(int i=0;i<maxNumberOfItems;i++)
{
b[i]="";//has to be an empty string, I am getting a segmentation fault
}
}
A::~A(){/*...*/}
//...
//in b.h
class B
{
private:
string name;
int price;
public:
void setName(string);
string getName();
void setPrice();
int getPrice(int);
B & operator=(string &);
};
//in b.cpp
B & B::operator=(string & a){name = a;price = 0; return *this;}
//...
this is only a snippet of the program showing my issue
You should allocate memory before using dynamic array.I have allocated memory for b
class A //in a.h
{
private:
B * b;
int maxNumberOfItems;
//...
public:
A();
~A();
void addB(const B & something);
};
//in a.cpp
A::A()
{
maxNumberOfItems=10;
b = new B[maxNumberOfItems];
for(int i=0;i<maxNumberOfItems;i++)
{
b[i]="";//has to be an empty string, I am getting a segmentation fault
}
}
A::~A(){/*...*/}
//...
//in b.h
class B
{
private:
string name;
int price;
public:
void setName(string);
string getName();
void setPrice();
int getPrice(int);
B & operator=(string &);
};
//in b.cpp
B & B::operator=(string & a){name = a;price = 0; return *this;}
It looks like class A is supposed to be a dynamic array class.
When you create a new instance of A you must also allocate memory for your array b. Which is just a pointer to some point in memory. From the code you posted, it doesn't get initialized and can point to any random memory place -- which is not good (i.e. the likely cause of your segfault).
I'd suggest making the following change.
A::A(){
maxNumberOfItems=10;
b = new B[maxNumberOfItems]; // b is an array of B objects.
// with default constructed values
// This way avoids the need for using a for loop and reassigning values
}
~A(){
if (b != NULL) { delete b; }
}
class B{
private:
//....
public:
B(): name(""), price(0) {}
// Although the default constructor without defining one should behave the same.
// This just makes it explicit. what name and price default to.
}
maxNumberOfItems=10;
//add this line to your code
b = new B[maxNumberOfItems];
//do some error check stuff
for(int i=0;i<maxNumberOfItems;i++)
{
b[i]="";//has to be an empty string, I am getting a segmentation fault
}
You don't allocate memory for b[i],so you get a segment fault.

Map referencing class used by same class

I have a class that needs to keep a list of references of all its objects.
For example:
//A.cpp
class A {
A() {}
someMethod() {}
someOtherMethod() { mapA[0]->someMethod(); }
}
//main.cpp
#include <map>
std::map<int, A*> mapA;
int main(int argc, char const *argv[]) {
int count = 0;
A* a = new A();
mapA[count] = a;
count++;
}
However, because mapA is only global to main.cpp, A.cpp can't reference it. I tried using extern, but because the map uses the same class A, I don't know where to put it.
What's the best way to go about this?
You might register them in constructor, and make the static var in the class:
// a.hpp
class A {
public:
A() { as.insert(this); }
A(const A& rhs) { as.insert(this); }
~A() { as.erase(this); }
static std::set<A*> as; // Declaration
};
// a.cpp
std::set<A*> A::as; // Definition

Base method gets called instead of derived method

I am currently trying to deliver more than one implementation of an header file. I tried doing this like this:
// A.h:
class A {
public:
A();
~A();
bool method1();
bool method2();
}
// A.cpp:
A::A() {
}
A::~A() {
}
bool A::method1() {
}
bool A::method2() {
}
// B.h
class B : public A {
public B();
public ~B();
bool method1();
bool method2();
}
// B.cpp
B::B() {
}
B::~B() {
}
bool B::method1() {
// actual code I want to use
}
bool B::method2() {
// actual code I want to use
}
// AFactory.h
#define USE_B 10
#define USE_C 20
#define IMPL USE_B
class A;
class AFactory {
public:
static A *getImplementation();
}
// AFactory.cpp
A *AFactory::getImplementation() {
#if IMPL == USE_B
return new B();
#elif IMPL == USE_C
return new C();
#else
return NULL;
#endif
}
// Test.cpp
int main () {
A *test = AFactory::getImplementation();
test->method1();
test->method2();
}
The idea was, to deliver more than one implementation of the class A, which could be switched by simply changing the value of the define IMPL. The problem is, that the methods from the actual used implementation B are never called. The methods from the base class A are called instead. I tried to remove the A.cpp completly from the build, since it's never used or rather should never be used, but then it won't build, telling me, that I have undefined references in my test code.
If you want to override these methods, you use the virtual keyword.
class A
{
virtual bool method1();
}
class B : public A
{
virtual bool method1(); // If you want to override the base functionality.
}

C++: Calling a Recursive function of an Abstact function

I would like to know how to call a recursive function of an abstract class using C++.
//A.h
class A {
public:
virtual void some() = 0 ;
};
//B.h
#include "A.h"
class B : public A {
public:
void some() ;
};
// B.cpp
void B::some(){
system("pause");
} ;
//C.h
#include "B.h"
class C : public B {
public:
static void callF() ;
};
// C.cpp
void C::callF(){
some();
} ;
I have edited the code. Still not working.
In A and B the function should be either public or protected.
Just use somefunction() inside the body of C::callingF() eg like
void C::callingF()
{
if (somecondition)
somefunction();
}
and you could use ptr->somefunction() if ptr is a pointer to some C or B i.e. a pointer to some A
But please, take hours to read a good book about the C++ programming language. We cannot explain it here in a few minutes. A book explains better...

Solving cross referencing

I have a problem creating some form of hierarchy with different object types. I have a class which has a member of another class, like this:
class A
{
public:
A(){}
~A(){}
void addB(B* dep){
child = dep;
dep->addOwner(this);
}
void updateChild(){
child->printOwner();
}
void print(){
printf("Printing...");
}
private:
B* child;
};
And this is class B:
class B
{
public:
void addOwner(A* owner){
ownerObject = owner;
}
//ISNT WORKING
void printOwner(){
ownerObject->print();
}
private:
A* ownerObject;
};
Calling a function of "B" out of class "A" works just fine but trying it vice versa gives a compiler error because A is not defined in B. It actually is by using an include and a forward declaration, but I guess its a cross reference problem which the compiler can not solve.
Is there any chance to solve this problem or should I rethink my design?
You say that you already solved your circular dependency problem by using a forward declaration of A instead of including the header where A is defined, so you already know how to avoid circular includes. However, you should be aware of what is possible and what is not with incomplete types (i.e. types that have been forward declared).
In your case, you try to call the member function print on an object that has an incomplete type; the compiler knows nothing about this type excepts that it will be defined at some point, so it does not allow you to do this. The solution is to remove the implementation of the printOwner member function from the B header and put it into an implementation file:
//B.hpp
class A; // forward declaration
class B
{
public:
void addOwner(A* owner);
void printOwner() const; // I think this member function could be const
private:
A* ownerObject;
};
//B.cpp
#include "B.hpp"
#include "A.hpp" // here we "import" the definition of A
void B::addOwner(A * owner)
{
ownerObject = owner;
}
void B::printOwner() const
{
ownerObject->print(); //A is complete now, so we can use its member functions
}
You could possibly do the same thing in the A header.
You can use forward declaration, and define the member functions outside of the class, i.e.
// A.h
class B;
class A { public:
void addB(B* dep); // don't define addB here.
...
};
// B.h
class A;
class B { public:
void addOwner(A* owner); // don't define addOwner here.
...
};
// A.cpp
#include "A.h"
#include "B.h"
void A::addB(B* dep) {
...
}
// B.cpp
// similar.
You probably should rethink your design, since a crcular parent-child relationship is usually a code smell.
But, you can make the compiler happy :
#include <cstdlib>
#include <cstdio>
class A
{
public:
A(){}
~A(){}
void addB(class B* dep);
void updateChild();
void print(){
printf("Printing...");
}
private:
class B* child;
};
class B
{
public:
void addOwner(A* owner){
ownerObject = owner;
}
//ISNT WORKING
void printOwner(){
ownerObject->print();
}
private:
A* ownerObject;
};
void A::addB(class B* dep){
child = dep;
dep->addOwner(this);
}
void A::updateChild(){
child->printOwner();
}
int main()
{
return 0;
}
You should move B::printOwner implementation to .cpp file.