Is the use of new/delete appropriate here? Or any way to avoid them?
The point: class myOptions need an instance of Submarine. The Parameter are known at the time the myOptions-Construcor is called.
#include <iostream>
#include <string>
class Submarine
{
public:
Submarine(std::string o)
{
std::cout << "create class Submarine: " << o << "\n";
}
~Submarine(){};
};
class myOptions
{
public:
myOptions(std::string o):option(o)
{
std::cout << "create class myOption: " << option << "\n";
submarine = new Submarine(option);
}
~myOptions()
{
delete submarine;
}
private:
std::string option{};
Submarine *submarine;
};
int main(void){
myOptions{"help"};
}
You don't need to use dynamic memory here:
class myOptions
{
public:
myOptions(std::string o):option(o), submarine(o)
{
std::cout << "create class myOption: " << option << "\n";
}
private:
std::string option{};
Submarine submarine;
};
If you really need to use dynamic memory allocation (and you are not allowed to use smart pointers), you must apply the rule of five to your class. Currently it will blow up your program anytime you decide to pass it by value.
Related
#include <iostream>
#include <string>
#include <vector>
//#include "V2d.h"
using namespace std;
class item {
public:
int value;
string description;
item() {}
virtual ~item() {}
virtual void display() {
cout << "Value: " << value << endl;
}
};
class Cat : public item {
public:
string name = "Cat";
Cat() {
value = 20;
description = "a cat";
}
void display() {
cout << "Name: " << name << endl;
cout << "Value: " << value << endl;
cout << "Description: " << description << "\n" << endl;
}
};
class Dog : public item {
public:
string name = "Dog";
Dog() {
value = 10;
description = "a dog";
}
void display() {
cout << "Name: " << name << endl;
cout << "Value: " << value << endl;
cout << "Description: " << description << "\n" << endl;
}
};
class v2d {
public:
int hitPoints;
enum ItemName {
APPLE, ORANGE
};
vector<item*> inventory;
v2d() {
}
~v2d() {
for (int i = 0; i < inventory.size(); i++) {
delete inventory[i];
}
inventory.clear();
}
v2d(const v2d& orig) : inventory(orig.inventory.size()) {
hitPoints = orig.hitPoints;
for (int i = 0; i < inventory.size(); ++i) {
inventory[i] = new item(*orig.inventory[i]);
}
cout << "Copied!" << endl;
}
void display() {
for (int i = 0; i < inventory.size(); i++) {
inventory[i]->display();
}
}
};
int main() {
v2d vect1;
vect1.inventory.push_back(new Cat());
vect1.inventory.push_back(new Dog());
vect1.inventory.push_back(new Dog());
vect1.inventory.push_back(new Cat());
vect1.inventory.push_back(new Dog());
vect1.display();
cout << "**************************\n" << endl;
v2d vect2(vect1);
vect2.display();
}
And where would I start with trying to overload the += and -= operators in v2d to subtract and add to the inventory vector?
I have gotten to the part of having the base class and the derived classes; I seem to be having trouble not using dynamic casting. Is there a simple way to deep copy a vector of derived class pointers via the copy constructor without using a clone() function?
To do this correctly two more things need to be added to the base class:
class item {
public:
virtual ~item() {}
The base class must have a virtual destructor.
virtual item *clone() const=0;
And an abstract method that's traditionally called clone(). Every one of your subclasses must implement clone(), typically by using a copy constructor:
class Cat : public item {
public:
item *clone() const override { return new Cat{*this}; };
The same thing is done for all other subclasses of item. Then, with this in place you can clone a vector of these objects, correctly:
for (int i = 0; i < inventory.size(); ++i) {
inventory[i] = orig.inventory[i]->clone();
}
I seem to be having trouble not using dynamic casting. Is there a simple way to deep copy a vector of derived class pointers via the copy constructor without using a clone() function?
clone is the traditional solution, but I will propose an alternative.
Consider using type erasure and value types. It will give the simplest use, by far, with more complexity to set it up. Value types generally interoperate more cleanly with a lot of the language and library. They are less intrusive. Standard types can satisfy your interfaces. There is no inheritance required. Value types do not require pointers and indirection everywhere. Those are but a few of the advantages.
With C++20, we can define a concept for item, which is an interface by another name:
template <typename Item>
concept item = std::copyable<Item> && requires(const Item& const_item, Item& item) {
{ item.value() } -> std::same_as<int&>;
{ const_item.value() } -> std::same_as<const int&>;
{ item.description() } -> std::same_as<std::string&>;
{ const_item.description() } -> std::same_as<const std::string&>;
{ item.display() };
{ const_item.display() };
};
Prior to C++20, concepts were generally implicit or documented, but not entities in code. But in C++20, we can define them. Note that this formulation requires std::copyable so any item satisfying this will be copyable, using the standard copy constructor. Also, note that raw data members in an interface complicate things slightly, so I replaced them with accessors while still allowing the public read and write access the code in the question allows.
With the interface defined, one can then define a type-erased version: define a type any_item satisfying item which can itself hold a value of any type satisfying item. You will likely find many online sources about type erasure, and the choices involved. The key is to have storage for the object, and a table of function pointers for the interface (a vtable). One can store the object on the heap or have a small internal buffer for small objects. One can store the vtable inline or store a pointer to the vtable. One can write the vtable explicitly, or rely on a hidden class hierarchy to coerce the compiler into writing one. One can even rely on a library (e.g. dyno) to do this for you.
Note that all this complexity is handled by the interface or library author. The user does not have to inherit anything. The user does not have to define boilerplate clone functions. The user only has to define the functions the concept requires. Then the user can use the type-erased type, and use it like any other value type. The user can put them in a std::vector and watch the copy constructor just work.
Code that looked like:
std::vector<item*> inventory;
~v2d()
{
for (auto* item: inventory) {
delete item;
}
}
v2d(const v2d& orig) :
inventory(orig.inventory.size())
{
for (int i = 0; i < inventory.size(); i++) {
inventory[i] = new item(*orig.inventory[i]);
}
cout << "Copied!" << endl;
}
vect1.inventory.push_back(new Cat());
Becomes:
// just use values
std::vector<any_item> inventory;
// destruction just works
~v2d() = default;
// copy just works
v2d(const v2d& other) :
inventory(other.inventory)
{
std::cout << "Copied!\n";
}
// just use values, again
vect1.inventory.push_back(cat());
See an example
My colleague and I are implementing Google Test for our code base and are running into a few issues with Contravariance regarding using standard template containers.
So, Google Test requires us to make a pure virtual Interface class that mirrors our actual class which will inherit the interface and implement all virtual functions. This is to be used in Google Mock for testing. This is a strict requirement to work too, otherwise we need to add templates to all of our classes which will only be of one type... this seems rather unintuitive just to get the test code working.
So we just investigated some code that exhibits the behavior of the issue:
#include <vector>
#include <string>
#include <iostream>
class Fruit{
public:
Fruit(std::string colorIn) : color(colorIn) {}
std::string color;
};
class Apple : public Fruit{
public:
Apple() : Fruit("Red"){ appleType = "Honey Crisp"; }
Apple(const Fruit& fruit) : Fruit(fruit.color) { appleType = "Honey Crisp"; }
std::string appleType;
};
class Banana : public Fruit{
public:
Banana() : Fruit("Yellow"){ bananaType = "Dole"; }
Banana(const Fruit& fruit) : Fruit(fruit.color) { bananaType = "Dole"; }
std::string bananaType;
};
void takeMyFruit(std::vector<Fruit>& fruits){
if(!fruits.empty()){
std::cout << "Take my " << fruits[0].color << " " << ((Banana)(fruits[0])).bananaType << " banana." << std::endl;
std::cout << "Take my " << fruits[1].color << " " << ((Apple)(fruits[1])).appleType << " apple." << std::endl;
}else{
std::cout << "You gave me an empty bag?" << std::endl;
}
}
int main(){
std::vector<Fruit> fruits;
fruits.push_back(Banana());
fruits.push_back(Apple());
std::vector<Banana> bananas = { Banana() };
std::vector<Apple> apples = { Apple() };
takeMyFruit(fruits); //Why can I do this?
//takeMyFruit(bananas); //Compile error due to contravariance
//takeMyFruit(apples); //Compile error due to contravariance
return 0;
}
We need to be able to compile something that can take a base type for a container, i.e. std::vector<BaseType>, but we are only populating it with one single DerivedType.
Why would we be allowed to mix two different derived types in the std::vector<Fruit> in the above code example we created, (i.e. Apple and Banana), but not be able to pass a std::vector<DerivedType> to a functional parameter that accepts std::vector<BaseType>?
What would be the best way to get around this issue regarding Google Test and Google Mock. They say that if production code is being changed to suit the need for tests, then it probably isn't the best practice.
Another way to do this that we saw was to add templates for the derived types to any class that defines them as members. Doing this would be a rather large rehaul and would then require any user of the library we're creating to have to wrap every instantiation of these new classes that hold these interface/derived types just to get Google Mock to work.
We're operating on legacy code at this point that can't be changed this much to incorporate Google Mock. We can't just skip testing these new class types either, what would be the best method for moving forward?
Please see the code below.
#include <vector>
#include <string>
#include <iostream>
#include <memory>
using namespace std;
class Fruit
{
public:
Fruit(std::string colorIn) : color(colorIn) { }
std::string color;
};
class Apple : public Fruit{
public:
Apple() : Fruit("Red") { appleType = "Honey Crisp"; }
Apple(const Fruit& fruit) : Fruit(fruit.color) { appleType = "Honey Crisp"; }
std::string appleType;
};
class Banana : public Fruit{
public:
Banana() : Fruit("Yellow") { bananaType = "Dole"; }
Banana(const Fruit& fruit) : Fruit(fruit.color) { bananaType = "Dole"; }
std::string bananaType;
};
void takeMyFruit(std::vector<shared_ptr<Fruit>>& fruits)
{
if (!fruits.empty())
{
for (vector<shared_ptr<Fruit>>::const_iterator it = fruits.begin(); it != fruits.end(); ++it)
std::cout << "Take my " << (*it)->color;
// You shouldn't use the following two lines as you don't know what is in the vector.
// std::cout << "Take my " << fruits[0]->color << " " << std::dynamic_pointer_cast<Banana>(fruits[0])->bananaType << " banana." << std::endl;
// std::cout << "Take my " << fruits[1]->color << " " << std::dynamic_pointer_cast<Apple>(fruits[1])->appleType << " apple." << std::endl;
}
else
{
std::cout << "You gave me an empty bag?" << std::endl;
}
}
int main()
{
std::vector<std::shared_ptr<Fruit>> fruits;
fruits.push_back(std::make_shared<Banana>());
fruits.push_back(std::make_shared<Apple>());
std::vector<std::shared_ptr<Fruit>> bananas = { std::make_shared<Banana>() };
std::vector<std::shared_ptr<Fruit>> apples = { std::make_shared<Apple>() };
takeMyFruit(fruits); //Why can I do this?
takeMyFruit(bananas); //OK now
takeMyFruit(apples); //OK now
return 0;
}
If you want to have a functionality to show the fruit type, the correct way is to add a virtual function in Fruit
virtual string FruitDetailType() = 0;
and implement it in the derived class - lets say, apple class
virtual string FruitDetailType()
{
return "Apple, Honey Crisp";
}
//or,
virtual string FruitDetailType()
{
return appleType;
}
I am a learner of C++. I have compiled the below program. I am working on constructors and destructors concept. I have this code here below where I declare a private destructor and access the private members using member function of the class from main(). I know that a private constructor can be declared but is a public constructor also mandatory? here is my code below:
class Book
{
private:
int *pages;
int *price;
Book() //default constructor
{
pages = new int;
price = new int;
*pages = 300;
*price = 8;
}
public:
void pre_destructor()
{
std::cout << "The pages:" << *pages << "\n";
std::cout << "The price:" << *price << "\n";
}
~Book() //destructor
{
std::cout << "The pages:" << *pages << "\n";
std::cout << "The price:" << *price << "\n";
delete pages;
delete price;
}
};
int main()
{
using namespace std;
Book book1;
cout << "Before using destructors" << endl;
cout << "---------------------------------"<< endl;
book1.pre_destructor();
cout << "After using destructors" << endl;
cout << "---------------------------------";
return 1;
}
For the above program, two errors are shown. One is in the main function where an object is declared; Error: error within content. And the second one is in the line where the constructor is called; Error:Book::Book() is private.
The main is not directly accessing the constructor in the code. Then why does it shows the access error?
No, a public constructor is not mandatory. There are use cases for private constructors.
A class with only static methods might have private (or deleted) constructors to prevent instances being created.
A singleton class (where only one instance of the class exists) might enforce its singleton status by having a private constructor. That instance can be accessed through a static getter.
You might want to follow a builder or factory pattern, where you force your users to construct instances using a process beside calling the constructor. That builder or factory would be either a member of the class or a friend, so able to call a private constructor. This scheme is much more common in Java than C++, but C++ allows it as well.
That said, you're looking to simply construct an instance of a class:
Book book1;
This use definitely requires a public default constructor.
When you make a constructor private, you need to expose a method so that external classes/methods can create object of this class. You'd do so by creating a static method, which in turn creates the object.
following code demonstrates:
#include <iostream>
class Book
{
private:
int *pages;
int *price;
Book() //default constructor
{
pages = new int();
price = new int();
*pages = 300;
*price = 8;
}
public:
static Book* constructBook()
{
return new Book();
}
void pre_destructor()
{
std::cout << "The pages:" << *pages << "\n";
std::cout << "The price:" << *price << "\n";
}
~Book() //destructor
{
delete pages;
delete price;
}
};
int main()
{
Book* book1 = Book::constructBook();
std::cout << "Before using destructors" << endl;
std::cout << "---------------------------------"<< endl;
book1->pre_destructor();
cout << "After using destructors" << endl;
cout << "---------------------------------";
delete book1;
return 0;
}
Not at all ! You don't need a public constructor but you need a factory fuction to create an instance of that class & in that case you need to qualify that function with the keyword static. See below :-
#include <iostream>
using namespace std;
class X
{
int x;
X(int x)
{
cout<<"creation\n";
this->x = x;
}
public:
static X make_X (int x) // without static error message will be : error: cannot call member function 'X X::make_X(int)' without object
{
return X(x);
}
int& getx()
{
return x;
}
~X()
{
cout<<"destruction\n";
}
};
int main()
{
auto obj = X::make_X(5);
auto ano = X::make_X(7);
cout << obj.getx() << '\t' << ano.getx() << '\n';
return 0;
}
Output is :-
creation
creation
5 7
destruction
destruction
There is no need of a public contrcutor here. But you needed make_X to create an instance of the class.
You can also use friend instead of static. In that case the code will be :-
friend X make_X (int x); // declare a prototype in the class
Then define outside the class definition :-
X make_X (int x)
{
return X(x);
}
That's how it works ! Cheers!!
ObjectInfo class is a diagnostic class intended to track statistical data such as life time and number of objects. A specific class inherits from ObjectInfo as shown. A member of that specific class is then declared in the body of a profiled class.
Although the solution works it is hard to maintain as it requires the profiling class to be keep in sync with the profiled class as the class name is used to identify the later. It would also be hard to extend the profiling class to gather different information such as the size of object.
Propose a better solution where the dependencies between the profiled and profiling classes are minimal.
Is it possible to implement a check that would determine if the object of the profiled class was created on stack or heap?
-- ObjectInfo.h --
#pragma once
class ObjectInfo
{
public:
ObjectInfo(const char* objectName);
virtual ~ObjectInfo(void);
private:
static int m_counter;
int m_objectNumber;
const char* m_className;
};
-- ObjectInfo.cpp --
#include "StdAfx.h"
#include "ObjectInfo.h"
#include <iostream>
#include "TimePrinter.h"
using namespace std;
int ObjectInfo::m_counter = 0;
ObjectInfo::ObjectInfo(const char* name) :
m_className(name)
{
m_objectNumber = ++m_counter;
cout << "Object: " << m_className << "# " << m_objectNumber << " created # " <<
TimePrinter()<< endl;
}
ObjectInfo::~ObjectInfo(void)
{
cout << "Object: " << m_className << "# " << m_objectNumber << " destroyed # " <<
TimePrinter() << endl;
}
-- The use pattern --
struct _AInfo : public ObjectInfo {
_AInfo() : ObjectInfo("_A") {}
};
struct _A {
_AInfo m_info;
};
I originally thought this question is asking about using C++ reflection technique to gather the runtime information. However, I don't know if there is a way to measure the lifetime of objects using C++ reflection. Furhter, can you consider C++ reflection is a technique that reduces the dependencies between the profiled and profiling classes ?
This can track stack vs. heap object creations
#include <iostream>
template <class CRTP>
struct AllocationTracker
{
AllocationTracker()
{
++totalCreated;
}
void* operator new(size_t sz)
{
++heapCreated;
return ::operator new(sz);
}
static int totalCreated;
static int heapCreated;
};
template <class CRTP>
int AllocationTracker<CRTP>::totalCreated;
template <class CRTP>
int AllocationTracker<CRTP>::heapCreated;
class Derived : public AllocationTracker<Derived>
{
};
int main()
{
using namespace std;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 0/0
Derived dStack;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 0/1
Derived* dHeap = new Derived;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 1/2
}
This uses the CRTP that Bartek brought up in the comments on your question. This lets us track each derived type separately. It also wraps the standard new for the base class, which is inherited by derived classes, which allows us to track heap allocations. So we know how many instances are created, and how many on the heap, and we can infer that the rest were on the stack (unless you're using object pools or some other more exotic allocation strategies in your program).
I've messed up something.
Here is the code:
#include <iostream>
class connection_c {
private:
std::string data_;
void (*saveCallBack_)();
public:
connection_c(std::string &data) : data_(data) { std::cout << "ctor: " << __FUNCTION__ << ":" << data_ << std::endl;}
void registerCallBack(void(*cb)()) { saveCallBack_ = cb; }
};
class inst_c {
private:
static int id;
connection_c conn;
static void cb() { std::cout << __FUNCTION__ << " id = " << id << std::endl; }
public:
inst_c(connection_c &c, int a) : conn(c), id(a) {
std::cout << "ctor: " << __FUNCTION__ << " " << id << std::endl;
conn.registerCallBack(&cb);
}
};
class group_inst_c {
private:
connection_c conn;
inst_c i,j,k;
public:
group_inst_c(std::string data) : conn(data), i(conn,1), j(conn,2), k(conn,3) {}
};
int main() {
group_inst_c gi("asdf");
return 0;
}
What I want to achieve ;)
create a group of instances (group_inst_c)
it should initialize single connection for the group (connection_c)
each instance (inst_c) should use this connection (it will be serialized)
.. in addition each instance should register separate callback
For sure I've messed up with cloning, but I guess probably not only.
Can someone help me solve this puzzle? thx.
Your code creates a copy of your connection object for each instance. The original connection object is then only accessible by your group_inst_c. Is this what you want? If not, you need to change:
class inst_c {
private:
static int id;
connection_c& conn; // <-- Needs to be a reference.
in addition each instance should register separate callback
I'm not sure what you mean here. Are the callbacks supposed to be member functions? Then you need to use a "pointer to member function" (the ::*, .*, and ->* operators). If the callbacks are supposed to be regular functions, you should be okay with your current code. You'll just need to add this to class connection_c:
void doCallback(void) { (*saveCallBack_)(); }
If I understood that correctly (you want to call several callbacks from a single connection [object]), you need a list in connection_c to register the callbacks (just like delegates in C# if you know them).
If an event occurs to this connection, it has to know where to report. So you have to iterate through the callbacks somehow (call them one by one; you cannot call them all at once). The easiest, straightforward way is to use an STL list or maybe boost offers something appropriate.
Take a look at this: A C++ delegate class. In the main function, there's a vector defined that takes multiple callbacks. You could use this pattern in you connection_c class to add and not set a callback.
Try to keep it simple at first. There's always an opportunity to grow/improve the design later on. Below is some example code and here are a couple of things I was thinking about while building it:
1) As mentioned, keep it simple. For example, maybe the group concept can be a vector (i.e. inst_group_t) to start. You can always grow the design later as you learn more about it.
2) Try to reduce class dependencies. For example, maybe I do not need to have the connection as a member variable. I can pass it in when its needed (i.e. execute()). Maybe the callback doesn't need to be registered (i.e. execute()), since its 1 connection_c to many inst_c instances registering a callback for each inst_c would mean connection would have some container. Keep it simple :)
3) Try to use const and reference as much as possible (i.e. connection_c constructor). Less copy constructors/temp objects will be created.
#include <iostream>
class connection_c {
private:
std::string data_;
public:
connection_c(const std::string &data) : data_(data) {
std::cout << "ctor: " << __FUNCTION__ << ":" << data_ << std::endl;
}
};
class inst_c {
private:
int id;
public:
inst_c(int a) : id(a) {
std::cout << "ctor: " << __FUNCTION__ << " " << id << std::endl;
}
typedef void (*execute_callback_t)(int i);
void execute(connection_c& connection, execute_callback_t callback) {
callback(id);
}
};
void mycallback(int id) {
std::cout << "Instance number " << id << " executed" << std::endl;
}
int main() {
typedef std::vector<inst_c*> inst_group_t;
inst_group_t group;
std::string data;
connection_c connection(data);
for (int i = 0; i < 10; ++i)
group.push_back(new inst_c(i) );
for (int i = 0; i < 10; ++i)
group[i]->execute(connection, mycallback);
for (int i = 0; i < 10; ++i)
delete group[i];
return 0;
}