I would like to learn how to define a derived class constructor in one file so that I could implement it in another file.
public:
Derived(std::string name) : Base(name);
~Derived();
Destructor works as expected, however with constructor I either add {} at the end (instead of a semicolon) and then get redefinition of 'Derived' error or I get asked to add {} instead of a semicolon. What is a way to separate definition and implementation in this case?
Base.h
#include <string>
class Base
{
protected:
std::string name;
...
public:
Base(std::string name);
virtual ~Derived();
...
};
Base.cpp
#include "Base.h"
Base::Base(std::string name)
: name(name)
{
...
}
Base::~Base()
{
...
}
Derived.h
#include "Base.h"
class Derived : public Base {
...
public:
Derived(std::string name);
~Derived();
...
};
Derived.cpp
#include "Derived.h"
Derived::Derived(std::string name)
: Base(name)
{
...
}
Derived::~Derived()
{
...
}
You do it the same way as for any other member function of the class. For example,
base.h
#pragma once
#include <string>
class Base
{
std::string name;
public:
Base() = default;
Base(std::string pname);//declaration
//other members
};
base.cpp
#include "base.h"
#include <iostream>
//definition
Base::Base(std::string pname): name(pname)
{
std::cout<<"Base constructor ran"<<std::endl;
}
derived.h
#pragma once
#include "base.h"
class Derived : public Base
{
public:
Derived(std::string pname);//declaration
};
derived.cpp
#include "derived.h"
#include <iostream>
//definition
Derived::Derived(std::string pname): Base(pname)
{
std::cout<<"Derived constructor ran"<<std::endl;
}
main.cpp
#include <iostream>
#include "derived.h"
#include "base.h"
int main()
{
Derived d("anoop");
return 0;
}
You can separate declaration and definition like so:
class Derived : public Base {
public:
Derived(std::string name); // declaration
// ... other members here
};
Then, elsewhere:
// definition
Derived::Derived(std::string name) : Base(name) {
// ...
}
Related
I have following C++ code
AbstractClass_01.h
class AbstractClass_01 {
public:
virtual void method_01() = 0;
};
AbstractClass_02.h
class AbstractClass_02 {
public:
virtual void method_02() = 0;
};
ClassA.h
#include "AbstractClass_02.h"
class ClassA : public AbstractClass_02{
public:
void method_02();
void method_03();
};
ClassA.cpp
#include "ClassA.h"
void ClassA::method_02() {}
void ClassA::method_03() {}
ClassB.h
#include "AbstractClass_01.h"
#include "AbstractClass_02.h"
class ClassB : public AbstractClass_01 {
public:
ClassB(AbstractClass_02& _obj);
void method_01();
private:
AbstractClass_02 &obj;
};
ClassB.cpp
#include "ClassB.h"
#include "ClassA.h"
ClassB::ClassB(AbstractClass_02& _obj) : obj(_obj) {}
void ClassB::method_01() {
static_cast<ClassA&>(obj).method_03();
}
main.cpp
#include "ClassA.h"
#include "ClassB.h"
int main(int argc, char** argv) {
ClassA a;
ClassB b(a);
b.method_01();
return 0;
}
My question is whether the casting which I have done in the ClassB::method_01 is common C++ construct whether it is a sign of wrong design?
EDIT:
The reason why the ClassB constructor accepts references to the AbstractClass_02 instead of the ClassA is that I need to pass references to various objects which all have common interface AbstractClass_02. The problem is that this interface doesn't contain the method_03. One possible solution could be to append that method into the interface AbstractClass_02 but that method isn't cohesive with the method_02.
This is known as downcasting and is typically a sign of bad design. Based on the limited knowledge we have, it seems obvious that you should take ClassA in constructor instead of AbstractClass_01
#include "AbstractClass_01.h"
#include "ClassA.h"
class ClassB : public AbstractClass_01 {
public:
ClassB(ClassA & _obj);
void method_01();
private:
ClassA &obj;
};
But we don't know your real problem and why did you decide to go with casting or accepting interface in the first place.
I have been attempting to use GoogleMock to override a few specific methods in a underlying class, however I seem to be getting the base constructor, rather than the mocked object. Is there something obvious I am missing here?
I have been following the following example:
http://blog.divebomb.org/2011/07/my-first-c-cmake-googletest-and-googlemock/
However, in my test, I am still getting my 'printf' called. Any thoughts?
Here are the classes/header files:
A.h:
#pragma once
class A
{
public:
virtual void methodToOverride();
void someConcreteMethod();
int mMemberVariable;
};
A.cpp:
#include "A.h"
void A::methodToOverride()
{
std::printf("Hello World");
}
void A::someConcreteMethod()
{
}
B.h:
#include "A.h"
class B
{
public:
B(A &injectedClass);
~B();
void MethodToTest();
private:
A mA;
};
B.cpp:
#include "B.h"
B::B(A & injectedClass):mA(injectedClass)
{
mA.someConcreteMethod();
}
B::~B(){}
void B::MethodToTest()
{
mA.methodToOverride();
}
MockA.h:
#include "A.h"
#include "gmock\gmock.h"
class MockA : public A
{
public:
MOCK_METHOD0(methodToOverride, void());
};
BTest.cpp:
#include "gtest/gtest.h"
#include "MockA.h"
#include "B.h"
using ::testing::AtLeast;
using ::testing::_;
TEST(BTest, mockObject)
{
// Arrange
MockA injectedMock;
EXPECT_CALL(injectedMock, methodToOverride())
.Times(AtLeast(1));
B classUnderTest(injectedMock);
// Act
classUnderTest.MethodToTest();
}
One major problem is that B::mA is an instance of the A class. It doesn't know anything about child-classes and objects.
The member B::mA either needs to be a reference or a pointer for polymorphism to work.
I have the header file
#ifndef CATEGORY_H
#define CATEGORY_H
#include <functional>
#include <string>
#include <vector>
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
class Rule : public Category
{
private:
std::function<void(int)> rule;
protected:
public:
Rule();
Rule(std::function<void(int)> rule);
};
#endif
in which the command std::vector<Rule> setOfRules; gives the error that Rule was not yet declared.
Switching the order of the declarations of the two classes gives
#ifndef CATEGORY_H
#define CATEGORY_H
#include <functional>
#include <string>
#include <vector>
class Rule : public Category
{
private:
std::function<void(int)> rule;
protected:
public:
Rule();
Rule(std::function<void(int)> rule);
};
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
#endif
but then I get the error that expected class-name before ‘{’ token for the line class Rule : public Category.
How do I solve this?
You can use a forward declaration for class Rule ( based on the first example ).
class Rule;
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
// class Rule definition here
Check here
You can forward declare class Rule:
#ifndef CATEGORY_H
#define CATEGORY_H
#include <functional>
#include <string>
#include <vector>
class Rule; // <-- here
class Category
{
private:
std::string nameCategory;
std::vector<Rule> setOfRules;
protected:
public:
Category();
Category(std::string nameCategory);
void setIndexBankAccountEntry(unsigned int iBankAccountEntry);
};
class Rule : public Category
{
private:
std::function<void(int)> rule;
protected:
public:
Rule();
Rule(std::function<void(int)> rule);
};
#endif
I have a base class :
base.cpp:
#include "base.h"
base::base()
{
}
base::~base() {
}
void base::baseMethod(int a)
{
std::cout<<"base::baseMethod : "<<a<<std::endl;
}
base.h
#ifndef BASE_H
#define BASE_H
#include <iostream>
class base {
public:
base();
base(const base& orig);
virtual ~base();
void baseMethod(int);
private:
};
#endif /* BASE_H */
And I have derivative class which derive from base
derivative.cpp
#include "derivative.h"
derivative::derivative() : base(){
}
derivative::~derivative() {
}
void derivative::baseMethod(int a)
{
std::cout<<"derivative::baseMethod : "<<a<<std::endl;
}
void derivative::derivativeMethod(int a)
{
baseMethod(a);
derivative::baseMethod(a);
}
derivative.h
#ifndef DERIVATIVE_H
#define DERIVATIVE_H
#include "base.h"
class derivative : public base{
public:
derivative();
derivative(const derivative& orig);
virtual ~derivative();
void derivativeMethod(int);
void baseMethod(int);
private:
};
#endif /* DERIVATIVE_H */
main.cpp
derivative t;
t.baseMethod(1);
t.derivativeMethod(2);
and output is :
derivative::baseMethod : 1
base::baseMethod : 2
base::baseMethod : 2
When I call baseMethod with derivative class object, actually I am using baseMethod of derivative class . But when I call derivetiveMethod, I am using baseMethod of base class. Why is that ? and how can I call baseMethod of derivative class ?
Thanks.
I am using Netbeans 8.2, Windows 7 x64, g++ 5.3.0 (mingw)
You need to make baseMethod virtual in the base class:
virtual void baseMethod(int);
You don't need to "re-affirm" the virtualness in the child classes, but some folk do that for clarity. (That also includes the destructor in the child class).
I am implementing a pure virtual function from a parent class in a subclass.
When I try to instantiate the subclass in eclipse it says
The type 'derived' must implement the inherited pure virtual method 'Base::compareTo'
I am pretty sure I did so. My base class is..
base.h
#ifndef BASE_H_
#define BASE
class Base{
public:
Base();
virtual ~Base();
virtual int compareTo(void* compare)=0;
};
#endif /* BASE*/
Then my derived.h
#ifndef DERIVED_H_
#define DERIVED_H_
#include "Base.h"
class Derived : public Base {
public:
int x;
Derived(int y);
virtual ~Derived();
int compareTo(void* compare);
};
#endif /* DERIVED_H_ */
Derived.cpp
#include "Derived.h"
#include "Base.h"
Derived::Derived(int y) {
// TODO Auto-generated constructor stub
x=y;
}
Derived::~Derived() {
// TODO Auto-generated destructor stub
}
int Derived::compareTo(void* compare) {
Derived* compared;
int result=0;
if(compared=dynamic_cast<Derived*>(compare))
{
if(x<compared->x)
{
result=-1;
}
else
{
result=1;
}
}
return result;
}
I'm assuming this message is from eclipses code analyzer and not from your compiler. The code analyzer is wrong and you are correct. You have correctly implemented the pure virtual method from the base class in Derived. If you try to instantiate Derived, the code should compile.
Might your CDT version be less than 8.2.1? If so, you may be encountering this bug which should be fixed in 8.2.1.
There is another bug in your code though. You can't dynamic_cast a void pointer.
try this code of Base class:
#ifndef BASE_H_
#define BASE_H_
class Base{
public:
//Base (); not needed in the virtual class
virtual ~Base() {};
virtual int compareTo(void* compare)=0;
};
#endif /* BASE*/
#ifndef DERIVED_H_
#define DERIVED_H_
#include "Base.h"
class Derived : public Base {
public:
int x;
Derived(int y);
virtual ~Derived();
int compareTo(void* compare) override/*C++11*/;
};
#endif /* DERIVED_H_ */
#include "Derived.h"
//#include "Base.h" Not needed
Derived::Derived(int y) {
// TODO Auto-generated constructor stub
x=y;
}
Derived::~Derived() {
// TODO Auto-generated destructor stub
}
int Derived::compareTo(void* compare) {
Derived* compared;
int result=0;
if(compared=dynamic_cast<Derived*>(compare))
{
if(x<compared->x)
{
result=-1;
}
else
{
result=1;
}
}
return result;
}