nullptr can't use in valarray - c++

Why can't use nullptr in the constructor function?( the function name: Wine) When i try to do this, the program will break down and no any error report maybe because i don't the reason for that.
#ifndef WINE_H_
#define WINE_H_
#include<iostream>
#include<string>
#include<valarray>
using std::string;
using std::valarray;
template<typename T1, typename T2>
class Pair //member of the wine
{
private:
T1 a;
T2 b;
public:
T1 & first(){ return a; }
T2 & second(){ return b; }
T1 first()const{ return a; }
T2 second()const{ return b; }
Pair(const T1 & aval, const T2 & bval) :a(aval), b(bval){}
Pair(){}
};
typedef valarray<int>ArrayInt;
typedef Pair<ArrayInt, ArrayInt>PairArray;
class Wine
{
private:
string name;
PairArray bt;
int years;
public:
Wine();
Wine(const char * a, int y,int b[], int c[]); //no problem
Wine(const char * a, int y); //here is that problem function
void GetBottles(); //no problem
void Show()const; //no problem
int Sum(){ return bt.second().sum(); }
};
Wine::Wine(const char * a, int y) :name(a), years(y), bt(ArrayInt(0, y), ArrayInt(0, y)){}
**//When I am trying to use nullptr to instead 0 in the ArrayInt(0,y),the whole program will break down during work.**
Wine::Wine(const char * a, int y, int b[], int c[]) :bt(ArrayInt(b, y), ArrayInt(c, y))
{
name = a;
years = y;
}
Wine::Wine() :bt(ArrayInt(),ArrayInt())
{
name = "null";
years = 0;
}
void Wine::GetBottles()
{
std::cout << "Please input the years and the bottles\n";
for (int i = 0; i < years; i++)
{
std::cout << "input the year: ";
(std::cin >> bt.first()[i]).get();
std::cout << "input the bottles";
(std::cin >> bt.second()[i]).get();
}
}
void Wine::Show()const
{
using std::cout;
using std::endl;
for (int i = 0; i < years; i++)
{
cout << bt.first()[i] << '\0' << bt.second()[i] << endl;
}
}
#endif
#include<iostream> //test part
#include"wine.h"
int main(void)
{
using std::cin;
using std::cout;
using std::endl;
cout << "Enter name of wine: ";
char lab[50];
cin.getline(lab, 50);
cout << "Enter number of years: ";
int yrs;
cin >> yrs;
Wine holding(lab, yrs);
holding.GetBottles();
holding.Show();
return 0;
}
Thank your for your help!

This is a funny one. The reason why it breaks in one example, but not another is following:
There are two different constructors for std::valarray (more than that, but those two matter):
valarray( const T& val, std::size_t count ); // 1
valarray( const T* vals, std::size_t count ); // 2
When you use 0 (valarray(0, y)) you are calling the first version - creating an array of y elements, where every element is initialized to 0.
But when you are calling it with nullptr, you are calling the second version of it - trying to initialize your new array with a copy from an array pointed to by the first argument to the constructor. But your first argument is nullptr, and any attempt to use at as an array triggers undefined behavior, and program crashes.

Related

Using a function pointer array to call a method of a class

I would like to write a program in C++ which contains an array of function pointers.
Here is the code:
#include <iostream>
using namespace std;
class MyClass {
int a, b;
public:
MyClass(int i, int j) : a(i), b(j) {}
int add() { return a + b; }
int sub() { return a - b; }
};
void func(int (MyClass::* funcPtr[])(), MyClass& a, int i) {
if (i == 0) {
funcPtr[i] = &MyClass::add;
funcPtr;
}
if (i == 1) {
funcPtr[i] = &MyClass::sub;
funcPtr;
}
cout << " Result: " << (a.*funcPtr[i])() << endl;
}
int main(){
int auswahl = 0;
int i = 4, j = 5;
cout << "Which function? [0]-Add [1]-Substract\n";
cin >> select;
MyClass a(i,j);
func(NULL, a, select);
}
After playing around a lot I got the program to compile successfully. But it throws "Write Access Violation" on running.
The problem seems to be related to:
funcPtr[i] = &MyClass::add;
funcPtr[i] = &MyClass::sub;
It'd be very nice, if you could help me solve the problem.
Thank you so much and have a happy time!
As you pass NULL or nullptr in your function, so this line:
funcPtr[i] = &MyClass::add;
Is writing at index i into a null array!
You'd have to provide an array for your function to write into:
MyClass a(i,j);
int (MyClass::* funcPtr[2])();
func(funcPtr, a, select);
Note that using std::array instead of c-style array would avoid this problem, since they are not nullable:
void func(std::array<int (MyClass::*)(), 2> funcPtr, MyClass& a, int i) {
// ...
}
// ...
std::array<int (MyClass::*)(), 2> funcPtr;
func(funcPtr /* cannot pass null */, a, i);

Getting an error "invalid use of non-static data member 'stu::n' "

#include <bits/stdc++.h>
using namespace std;
struct stu {
int n;
stu(int _n = 0):n(_n) { }
int add(int a, int b = n-1) {
return a + b;
}
};
int main() {
stu obj = stu(5);
cout << obj.add(10) << endl;
}
The compiler shows the message " invalid use of
non-static data member 'stu::n' ".
What is wrong with this code. Any help would be great.
Thanks.
You can't use default arguments this way. Consider writing two separate functions:
struct stu {
int n;
int add(int a, int b) { return a + b; }
int add(int a) { return a + n - 1; }
}

Identifier not found - error C3861 in Visual Studio 2019

I have a problem with my code. Unfortunately, when compiling I get these errors all the time. What can this be caused by and how to fix it?
error C3861: 'print': identifier not found
My code:
main.cpp
#include "pojazdy.h"
#include <iostream>
using namespace std;
int main()
{
Pojazdy** poj;
int size{ 0 }, index{ 0 };
Petla(poj, size);
print(poj, size);
wyrejestruj(poj,size,0);
print(poj, size);
wyrejestruj(poj,size);
return 0;
}
pojazdy.h
#ifndef pojazdy_h
#define pojazdy_h
#include <iostream>
#include <cstdlib>
using namespace std;
class Pojazdy
{
public:
string typ;
string marka;
string model;
string z_dod;
int ilosc;
int cena;
void dodaj();
void d_pojazd(Pojazdy**& pojazdy, int& size);
void wyrejestruj(Pojazdy**& pojazdy, int& size, int index);
void print(Pojazdy** pojazdy, int size);
void Petla(Pojazdy**& p, int& size);
//void wyswietl();
int get_ilosc() { return ilosc; }
string get_typ() { return typ; }
string get_marka() { return marka; }
string get_model() { return model; }
int get_cena() { return cena; }
void set_ilosc(int x);
};
#endif
pojazdy.cpp
#include "pojazdy.h"
#include <iostream>
using namespace std;
void Pojazdy::set_ilosc(int x) { ilosc = x; }
void Pojazdy::dodaj()
{
cout << "DODAWANIE POJAZDU..." << endl;
cout << "Podaj typ pojazdu:";
cin >> typ;
cout << "Podaj marke pojazdu: ";
cin >> marka;
cout << "Podaj model pojazdu: ";
cin >> model;
cout << "Dodaj cene pojazdu: ";
cin >> cena;
}
void Petla(Pojazdy**& p, int& size) {
char z_dod;// = 'N';
do {
d_pojazd(p, size); //odpowiada za dodawnie
p[size - 1]->dodaj();
cout << "Czy chcesz zakonczyc dodawanie? Jesli tak, wcisnij Y/N: ";
cin >> z_dod;
} while (z_dod == 'N' || z_dod == 'n');//while (p[size]->z_dod == "N" ||p[size]->z_dod == "n");
}
void print(Pojazdy** pojazdy, int size) {
std::cout << "====================================" << std::endl;
for (int i{ 0 }; i < size; i++)
std::cout << "Typ: " << pojazdy[i]->get_typ() << " Marka: " << pojazdy[i]->get_marka() << " Model: " << pojazdy[i]->get_model() << " Cena: " << pojazdy[i]->get_model() << std::endl;
}
void wyrejestruj(Pojazdy**& pojazdy, int& size) {
for (size_t i{ 0 }; i < size; i++)
delete pojazdy[i];
delete[] pojazdy;
size = 0;
pojazdy = NULL;
}
void wyrejestruj(Pojazdy**& pojazdy, int& size, int index) {
if (index < size) {
Pojazdy** temp = new Pojazdy * [size - 1];
short int j{ -1 };
for (size_t i{ 0 }; i < size; i++) {
if (i != index) {
j++;
temp[j] = pojazdy[i];
}
}
delete[] pojazdy;
--size;
pojazdy = temp;
}
else
std::cout << "Pamiec zwolniona!" << std::endl;
}
void d_pojazd(Pojazdy**& pojazdy, int& size) {
Pojazdy** temp = new Pojazdy * [size + 1];
if (size == 0)
temp[size] = new Pojazdy;
else {
for (int i{ 0 }; i < size; i++)
temp[i] = pojazdy[i];
delete[] pojazdy;
temp[size] = new Pojazdy;
}
++size;
pojazdy = temp;
}
I used #ifndef, #define, #endif and #pragma once, but none of them work. I will be really grateful for every code, I am already tired of this second hour. And forgive the non-English variables and function names for them - it's university code, so I didn't feel the need.
Move the functions below outside the class declaration.
void wyrejestruj(Pojazdy**& pojazdy, int& size, int index);
void print(Pojazdy** pojazdy, int size);
void Petla(Pojazdy**& p, int& size);
Or make them static and call like Pojazdy::print(poj, size);.
You declared a non-static member function print in the class definition
class Pojazdy
{
public:
// ...
void print(Pojazdy** pojazdy, int size);
//...
but you are trying to call it as a stand-alone function in main
print(poj, size);
So the compiler issues an error.
The declaration of the function as a stand alone function that at the same time is its definition in the file pojazdy.cpp is not visible in the module with main because this module includes only the header with the class declaration.
You should decide whether this function should be a member function of the class or a stand alone function.
You are not calling your member functions correctly. print can only be called on an object of type Pojazdy, so you need to do something like:
Pojazdy** poj;
int size{ 0 }, index{ 0 };
Pojazdy x; // Creates an object of Pojazdy called z
x.print(poj,size); // Calls the print method on x
Alternatively, if you don't want to have to declare an object, you could make the method static and just call it on the class.
In the .h file:
static void print(Pojazdy** pojazdy, int size);
And then in main:
Pojazdy** poj;
int size{ 0 }, index{ 0 };
Pojazdy::print(poj, size); // Calls the print method on the class
You put your function prototypes in the wrong place. They should be after the class decalration.
class Pojazdy
{
...
};
void print(Pojazdy** pojazdy, int size);
void wyrejestruj(Pojazdy**& pojazdy, int& size);
etc.
print is not a member of the Pojazdy class, so it's wrong to put the prototype inside the Pojazdy class declaration.

Priority queue for user-defined types

I have the below struct:
struct node {
float val;
int count;
}
I have several objects of this struct. Now, I want to insert these objects into a priority queue of STL such that the priority queue orders the items by count. Any idea on how to do so? Preferably a min-heap is preferred. I know how to do the above for primitive data types, not structs
Overload the < operator:
bool operator<(const node& a, const node& b) {
return a.count > b.count;
}
I have reversed the comparison to achieve min heap without passing extra arguments to the priority queue.
Now you use it like this:
priority_queue<node> pq;
...
Edit: take a look at this post which seems to be almost exact duplicate: STL Priority Queue on custom class
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
class Boxer{
public:
string name;
int strength;
};
struct Comp{
bool operator()(const Boxer& a, const Boxer& b){
return a.strength<b.strength;
}
};
int main(){
Boxer boxer[3];
boxer[0].name="uday", boxer[0].strength=23;
boxer[1].name="manoj", boxer[1].strength=33;
boxer[2].name="rajiv", boxer[2].strength=53;
priority_queue< Boxer, vector<Boxer>, Comp> pq;
pq.push(boxer[0]);
pq.push(boxer[1]);
pq.push(boxer[2]);
Boxer b = pq.top();
cout<<b.name;
//result is Rajiv
return 0;
}
Using greater as comparison function you can use priority queue as min heap,
#include <bits/stdc++.h>
using namespace std;
int main()
{
priority_queue<int,vector<int>,greater<int> >pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty())
{
int r = pq.top();
pq.pop();
cout << r << " ";
}
return 0;
}
Inserting value by changing their sign (using minus (-) for positive number and using plus (+) for negative number we can use priority queue in reversed order.
int main()
{
priority_queue<int>pq2;
pq2.push(-1); //for +1
pq2.push(-2); //for +2
pq2.push(-3); //for +3
pq2.push(4); //for -4
while(!pq2.empty())
{
int r = pq2.top();
pq2.pop();
cout << -r << " ";
}
return 0;
}
For custom data types or classes we need a to tell priority queue a way of knowing on which order it will sort our data.
struct compare
{
bool operator()(const int & a, const int & b)
{
return a>b;
}
};
int main()
{
priority_queue<int,vector<int>,compare> pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty())
{
int r = pq.top();
pq.pop();
cout << r << " ";
}
return 0;
}
For custom structure or class you can use priority_queue in any order. Suppose, we want to sort people in descending order according to their salary and if tie then according to their age.
struct people
{
int age,salary;
};
struct compare {
bool operator()(const people & a, const people & b)
{
if(a.salary==b.salary)
{
return a.age>b.age;
} else {
return a.salary>b.salary;
}
}
};
int main()
{
priority_queue<people,vector<people>,compare> pq;
people person1,person2,person3;
person1.salary=100;
person1.age = 50;
person2.salary=80;
person2.age = 40;
person3.salary = 100;
person3.age=40;
pq.push(person1);
pq.push(person2);
pq.push(person3);
while(!pq.empty())
{
people r = pq.top();
pq.pop();
cout << r.salary << " " << r.age << endl;
}
Same result can be obtained by operator overloading :
struct people
{
int age,salary;
bool operator< (const people & p) const
{
if(salary==p.salary)
{
return age>p.age;
} else {
return salary>p.salary;
}
}
};
In main function :
priority_queue<people> pq;
people person1,person2,person3;
person1.salary=100;
person1.age = 50;
person2.salary=80;
person2.age = 40;
person3.salary = 100;
person3.age=40;
pq.push(person1);
pq.push(person2);
pq.push(person3);
while(!pq.empty())
{
people r = pq.top();
pq.pop();
cout << r.salary << " " << r.age << endl;
}
You need to provide operator< for that struct. Something like:
bool operator<(node const& x, node const& y) {
return x.count < y.count;
}
Now you can use a priority queue from the standard library.
Since C++11, you can write
auto comparer = [](const auto& a, const auto& b) {
return a.priority < b.priority;
};
std::priority_queue<Item, std::vector<Item>, decltype(comparer)> queue(comparer);
We can define user defined comparator class:
Code Snippet :
#include<bits/stdc++.h>
using namespace std;
struct man
{
string name;
int priority;
};
class comparator
{
public:
bool operator()(const man& a, const man& b)
{
return a.priority<b.priority;
}
};
int main()
{
man arr[5];
priority_queue<man, vector<man>, comparator> pq;
for(int i=0; i<3; i++)
{
cin>>arr[i].name>>arr[i].priority;
pq.push(arr[i]);
}
while (!pq.empty())
{
cout<<pq.top().name<<" "<<pq.top().priority;
pq.pop();
cout<<endl;
}
return 0;
}
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class Person
{
public:
string name;
int age;
Person(string str,int num)
{
name = str;
age = num;
}
};
// FUNCTOR
class compare
{
public:
bool operator()(Person a,Person b)
{
cout << "Comparing " << a.age << " with " << b.age << endl;
return a.age < b.age;
}
};
int main()
{
int n;
cin >> n;
priority_queue <Person, vector<Person> , compare> pq;
for(int i=1;i<=n;i++)
{
string name;
int x;
cin >> name;
cin >> x;
Person p(name,x);
pq.push(p);
}
int k = 3;
for(int i=0;i<k;i++)
{
Person p = pq.top();
pq.pop();
cout << p.name << " " << p.age << endl;
}
return 0;
}
Operator() is also commonly overloaded to implement functors or function object. For example we have a structure Person which have some default ways of searching and sorting a person by age but we want our customized ways with some other parameter like weight so we may use our own custom functor. Priority queue is one such container which accepts a functor so it knows how to sort the objects of custom data types. Each time a comparison has to be done, a object is instantiated of class compare, and it is passed two objects of person class for comparison.

C++ valarray/template classes not working

this is my first post here but I've been a frequent reader of various topics here.
Now I'm stuck with a programming issue with c++, its basically a template class called "Pair" which should contain 2 valarrays of ints and then be included in another class called Wine. Problem is I'm not getting either the constructors right or the header file according to my compiler!
Take a look and please try to help me, the main issue is that it the valarrays wont take ints as arguments + i dont understand how i can convert a usual int array to a valarray with just 1 constructor argument:
#ifndef Derp
#define Derp
#include <valarray>
template <typename T1, typename T2>
class Pair
{
private:
T1 a;
T2 b;
public:
T1 & first();
T2 & second();
T1 first() const {return a;}
T1 second() const {return b;}
Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) {}
Pair() {}
};
template Pair<std::valarray<int>, std::valarray<int> >;
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
class Wine
{
private:
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
std::string name;
int years;
PairArray arr;
public:
Wine(const char * l, int y, const int yr[], const int bot[]);
Wine(const char * l, int y);
void GetBottles();
std::string Label();
int sum();
void show();
};
#endif
So, heres the header file, now comes the first .cpp file with all the function - definitions:
#include <iostream>
#include <valarray>
#include <cstring>
#include "K14O1.h"
template <typename T1, typename T2>
T1 & Pair<T1, T2>::first()
{
return a;
}
template <typename T1, typename T2>
T2 & Pair<T1, T2>::second()
{
return b;
}
Wine::Wine(const char * l, int y, const int yr[], const int bot[])
: arr(y, y)
{
name = l;
years = y;
for(int a = 0; a < y; a++)
{
arr.first()[a] = yr[a];
arr.second()[a] = bot[a];
}
}
Wine::Wine(const char * l, int y)
: arr()
{
name = l;
years = y;
arr.first() = y;
arr.second() = y;
}
void Wine::GetBottles()
{
for(int c = 0; c < years; c++)
{
std::cout << "Skriv in antal buteljer för det året: ";
std::cin >> arr.first()[c];
std::cout << "Skriv in årgång: ";
std::cin >> arr.second()[c];
}
}
std::string Wine::Label()
{
return name;
}
typedef std::valarray<int> ArrayInt;
int Wine::sum()
{
int b;
int ar = 0;
while(arr.second()[b])
{
ar += arr.second()[b];
b++;
};
return ar;
}
void Wine::show()
{
std::cout << "Vin: " << name << std::endl;
int b = 0;
while(arr.first()[b])
{
std::cout << arr.first()[b] << "\t" << arr.second()[b] << std::endl;
b++;
};
}
Finally the last .cpp file:
#include <iostream>
#include <valarray>
#include "K14O1.h"
using namespace std;
int main(int argc, char * argv[])
{
const int YRS = 3;
int y[YRS] = {1993, 1995, 1998};
int b[YRS] = {48, 60, 72};
Wine more("Gushing Grape Red", YRS, y, b);
cout << "Skriv in vinets namn: ";
char lab[50];
cin.getline(lab, 50);
cout << "Skriv in antal årgångar: ";
int yrs;
cin >> yrs;
Wine holding(lab, yrs);
holding.GetBottles();
holding.show();
more.show();
cout << "Totalt antal buteljer av " << more.Label()
<< ": " << more.sum() << endl;
cout << "HEJDASADAN" << endl;
return 0;
}
I would be enourmosly grateful if you guys could tell me whats wrong and how to fix it. Im currently doing stephen pratas C++ book and this is a exercise, thanks!
Any other general tips on coding would be wonderful aswell, have a good time!
What's wrong: Well, honestly, where do I start?
Firstly, there is a std::pair structure. Secondly, the valarray stuff was a total mistake and not at all used anymore. Thirdly, const char*, int[] arguments? Owch. Can you say buffer overrun and memory corruption? Fourthly,
int Wine::sum()
{
int b;
int ar = 0;
while(arr.second()[b])
{
ar += arr.second()[b];
b++;
}
return ar;
}
You didn't initialize b. Undefined behaviour.
The Definitive C++ Book Guide and List
This question lists good C++ books, and Stephen Prata is mentioned as having a very bad book. This code sample supports that. Burn your book and buy one that doesn't suck, would be my recommendation.