When initializing a struct using curly braces, it does not seem to work with an array of chars. I can write an equivalent constructor that works below. Is there any syntax so I don't have to write the constructor?
#include <cstdint>
#include <cstring>
using namespace std;
struct NamedLocationData {
uint16_t offset;
char stateName[21];
float lat;
float lon;
uint32_t population;
NamedLocationData(uint16_t offset, const char stateName[21],
float lat, float lon, uint32_t population)
: offset(offset), lat(lat), lon(lon), population(population) {
strncpy(this->stateName, stateName, 21);
}
};
int main() {
uint16_t nameOffset = 0;
char stateName[21] = "New York";
float lat = 40;
float lon = -74;
uint32_t population = 8000000;
#if 0
NamedLocationData temp = NamedLocationData
{
nameOffset, stateName, lat, lon, population
};
#endif
NamedLocationData temp( nameOffset, stateName, lat, lon, population);
}
Default constructors are one of the special member functions. If no constructors are declared in a class, the compiler provides an implicit inline default constructor.
I suggest you change char[] to string so that stateName will be able to get a value.
#include <cstdint>
#include <cstring>
#include <string>
using namespace std;
struct NamedLocationData {
uint16_t offset;
string stateName;
float lat;
float lon;
uint32_t population;
NamedLocationData(uint16_t offset, string stateName,
float lat, float lon, uint32_t population)
: offset(offset), lat(lat), lon(lon), population(population) ,
stateName(stateName){}
};
int main() {
uint16_t nameOffset = 0;
string stateName = "New York";
float lat = 40;
float lon = -74;
uint32_t population = 8000000;
#if 0
NamedLocationData temp = NamedLocationData
{
nameOffset, stateName, lat, lon, population
};
#endif
NamedLocationData temp(nameOffset, stateName, lat, lon, population);
return 0;
}
Result:
Related
I'm a complete noob, short-time lurker, first time poster.
I'm trying to build something for school, basing myself on prior builds, but it ends up having a ton of errors that I can't seem to root out, especially regarding the use of strings, the strcpys, and the const constructor.
Here is my cpp code:
#include "taxi.h"
#include <iostream>
#include <stdint.h>
#include <string>
#include <cstring>
using namespace std;
Taxi::Taxi(){
int interno = 0;
string marca = 'Marca';
string patente = 'AA 00 AA';
string Propietario = 'Apellido, Nombre';
int chofer = 0;
fadia = 1;
fames = 1;
fanio = 1970;
fbdia = 1;
fbmes = 1;
fbanio = 1970;
double tel = 0;
}
Taxi::Taxi(int inter, string marc, string pat, string prop, int ch, int dia_a,
int dia_b, int mes_a, int mes_b, int anio_a, int anio_b, double te){
int interno = inter;
string marca = marc;
string patente = pat;
string propietario = prop;
int chofer = ch;
fadia = dia_a;
fames = mes_a;
fanio = anio_a;
fbdia = dia_b;
fbmes = mes_b;
fbanio = anio_b;
double tel = te;
}
Taxi::~Taxi(){
cout<<"Destructor Activado. Fin del Programa."<<endl;
}
void Taxi::setPropietario(string prop){
strcpy(propietario, prop);
}
void Taxi::setChofer(int ch){
int chofer = ch;
}
void Taxi::imprimir(){
cout<<"Chofer en Servicio: "<<"\n -"<<chofer<<"\n -"<<propietario <<"\n -"<<tel<<endl;
cout<<"Vehiculo en Servicio: "<<"\n -"<<marca<<"\n -"<<patente<<endl;
cout<<"Fecha de alta: "<<fadia<<"/"<<fames<<"/"<<fanio<<endl;
cout<<"Fecha de baja: "<<fbdia<<"/"<<fbmes<<"/"<<fbanio<<endl;
}
and my header
#ifndef TAXI_H
#define TAXI_H
#endif // TAXI_H
#include <iostream>
#include <stdint.h>
#include <string>
#include <cstring>
class Taxi{
private:
int interno;
std::string marca;
std::string patente;
std::string propietario;
int chofer;
int fadia;
int fames;
int fanio;
int fbdia;
int fbmes;
int fbanio;
double tel;
public:
Taxi();
Taxi(int inter, std::string marc, std::string pat, std::string prop, int ch, int dia_a,
int dia_b, int mes_a, int mes_b, int anio_a, int anio_b, double te);
Taxi(const Taxi &);
~Taxi();
void setPropietario(std::string prop);
void setChofer(int inter);
void imprimir();
void imprimirtaxi();
};
I try to put an array of objects as a argument,
I know that you can initialize them separately with
constructorName (className array [], double arg2): name1 (arg1), name2(arg2){...}
But I can't do that with an array of objects, is there any other way to do this?
code example:
#include <iostream>
#include <string>
using namespace std;
class Atlet{
private:
string name;
int number;
string nacionality;
double time;
public:
Atlet(string n, int num, string nacio, double t){
name = n;
number = num;
nacionality = nacio;
time = t;
}
string getName(){
return name;
}
};
class Race{
private:
double distance;
Atlet runners[];
public:
//how to initalize arrays of objects here .
Race( Atlet arr[], double dist): runners(arr), distance(dist){
runners = arr;
distance = dist;
}
};
test.cpp program.
#include <iostream>
#include "bible.cpp"
using namespace std;
int main(){
Atlet t1 = Atlet("Usaimbol",12,"Madagascar", 10.21);
Atlet t2 = Atlet("Juan",15,"USA", 10.54);
Atlet comps[] = {t1, t2};
Race race1 = Race(comps, 120.00);
return 0;
}
I try to make this, but:
I want to say that Race( Atlet arr[], double dist): runners(arr), distance(dist){ should just be Race( Atlet arr[], double dist) { (taking out the colon stuff inline) but I cannot be certain.
I am writing a small utility class that transfor latitude and longitude coordinated into a UTM local system. For this task I am using this source. I created some struct to help me manage the majority of the data, but something is wrong if I pass data in a speciific way. It does work if I clearly re-state the values. See below the example:
zoneconverter.h
#ifndef ZONE_CONVERTER_H
#define ZONE_CONVERTER_H
#include <string>
#include <math.h>
#include <cmath>
#include <ctgmath>
#include <stdlib.h>
#include <stdio.h>
#include <stdexcept>
#define PI 3.14159265358979323846 /* pi */
#define SMaxA 6378137.0 /* semi major axis */
#define SMinA 6356752.314245 /* sdmi minor axis */
#define grid_size 100000.0 /* 100 km grid*/
struct Deg2Rad {
double D2R = PI/180.0;
};
struct Rad2Deg {
double R2D = PI*180.0;
};
// definition of the World Geodetic System 84
struct WGS84_DATA
{
double semi_major_axis_a = 6378137.0; // by definition
double semi_minor_axis_b = 6356752.314245; // by definition
const double flattening = (SMaxA-SMinA)/SMaxA; // by definition
const double first_eccentricity = 0.081891909; // by calculation
double second_eccentricity = 0.0820944377; // by calculation
double angular_velocity_earth = 72.92115e-6; // rad/s
double gravitational_constant = 3986004.418e8; // by definition
};
struct UTM_DATA
{
double point_scale_factor = 0.9996; // by convention
double equatorial_radius = 6378137.0; // meters also semi_major_axis_a
double inverse_flattening = 1/((SMaxA-SMinA)/SMaxA); // by convention
double northen_emisphere = 0.0; // meter
double southern_hemisphere = 10000000.0; // meter
double false_esting = 500000.0; // meter by convention
double first_eccentricity_power2 = 0.081891909*0.081891909;
double first_eccentricity_power4 = 0.081891909*0.081891909*0.081891909*0.081891909;
double first_eccentricity_power6 = 0.081891909*0.081891909*0.081891909*0.081891909*0.081891909*0.081891909;
};
enum UTMidentifierLeter {
X, W, V, U, T, S, R, Q, P, N,
M, L, K, J, H, G, F, E, D, C, Z
};
struct UTM_LETTER_ZONE { UTMidentifierLeter utmLetterZone; };
enum UTMIdentifierZone { NORWAY, SVALBARD };
struct UTM_ZONE { UTMIdentifierZone utmZone; };
class ZONE_converter
{
public:
ZONE_converter();
WGS84_DATA wgs84_data;
UTM_DATA utm_data;
Deg2Rad degreeToRad_reader;
Rad2Deg radToDeg_reader;
void UTM(double lat, double lon, double eastingUtmzone, double northingUtmzone);
char adjustForNorway(double lat);
char adjustForSvalbard(double lat, double lon);
char allOtherZones(double lat);
private:
UTM_LETTER_ZONE letter;
UTM_ZONE zone;
double latitude;
double longitude;
int current_zone;
};
#endif // ZONE_CONVERTER_H
zoneconverter.cpp is as following
#include "zone_converter.h"
ZONE_converter::ZONE_converter(){}
void ZONE_converter::UTM(double lat, double lon, double eastingUtmzone, double northingUtmzone)
{
double m0_a11 = (std::pow(wgs84_data.first_eccentricity, 4)/4);
double m0_a12 = (std::pow(wgs84_data.first_eccentricity, 4)/64);
double m0_a13 = (std::pow(wgs84_data.first_eccentricity, 6))/256;
double m0 = 1 - m0_a11 - 3*m0_a12 - 5*m0_a13;
double m1_a11 = (std::pow(wgs84_data.first_eccentricity, 2))/8;
double m1_a12 = (std::pow(wgs84_data.first_eccentricity, 4))/32;
double m1_a13 = (std::pow(wgs84_data.first_eccentricity, 6))/1024;
double m1 = -(3*m1_a11 + 3*m1_a12 + 45*m1_a13);
double m2_a11 = (std::pow(wgs84_data.first_eccentricity, 4))/256;
double m2_a12 = (std::pow(wgs84_data.first_eccentricity, 6))/1024;
double m2 = 15*m2_a11 + 45*m2_a12;
double m3_a11 = (std::pow(wgs84_data.first_eccentricity, 6))/3072;
double m3 = -35*m3_a11;
// calculation of the central meridian
int centralMeridian = ((lon >= 0.0)
? (static_cast<int>(lon) - (static_cast<int>(lon)) % 6 + 3)
: (static_cast<int>(lon) - (static_cast<int>(lon)) % 6 - 3));
double rlat = degreeToRad_reader.D2R;
double rlon = degreeToRad_reader.D2R;
double rlon0 = centralMeridian*degreeToRad_reader.D2R;
double slat = std::sin(rlat);
double clat = std::cos(rlat);
double tlat = std::tan(rlat);
double fn = (lat > 0) ? utm_data.northen_emisphere : utm_data.southern_hemisphere;
double T = tlat*tlat;
double C = (wgs84_data.first_eccentricity*wgs84_data.first_eccentricity)*clat*clat;
double A = (rlon - rlon0)*clat;
double M = (wgs84_data.semi_major_axis_a)*(m0*rlat + m1*std::sin(2*rlat) + m2*std::sin(4*rlat) + m3*std::sin(6*rlat));
// radius of curvature on the plane of the prime vertical
double Rn = wgs84_data.semi_major_axis_a/(std::sqrt(1 - std::pow((wgs84_data.first_eccentricity), 2)*slat*slat));
// radius of Curvature in the plane os the meridian
double Rc = ((wgs84_data.semi_major_axis_a)*(1 - ((wgs84_data.first_eccentricity)*(wgs84_data.first_eccentricity))))/(1 - ((wgs84_data.first_eccentricity)*(wgs84_data.first_eccentricity))*std::pow(std::sin(rlat), 2));
// computation of the easting-northing coordinate
eastingUtmzone = utm_data.point_scale_factor*Rn*(A + ((1-T+C)*(std::pow(A, 3)/6))+(5-18*T + std::pow(T,2) + 72*C - 58*(std::pow(wgs84_data.second_eccentricity, 2)))*(std::pow(A, 5))/120);
northingUtmzone = utm_data.point_scale_factor*((M - 0.0)+Rn*tlat*(((A*A)/2) + (((std::pow(A, 4))/24)*(5-T+9*C+4*C*C)) + (61 - 58*T + T*T + 600*C - 330*(std::pow(wgs84_data.second_eccentricity, 2))*((std::pow(A, 6))/720))));
(void) Rc;
(void) fn;
return;
}
main.cpp
#include <iostream>
#include "zone_converter.h"
using namespace std;
int main()
{
ZONE_converter convert;
double lat = 26.281742;
double lon = 92.142683;
double eastingUtmzone;
double northingUtmzone;
convert.UTM(lat, lon, eastingUtmzone, northingUtmzone);
std::cout<< lat << lon<< northingUtmzone<< eastingUtmzone<< std::endl;
return 0;
}
But I am trying to understand why if I write the function in the following way accessing the struct I created in header file I get a SIGSEV segmentation error:
void ZONE_converter::UTM(double lat, double lon, double eastingUtmzone, double northingUtmzone)
{
double m0_a11 = (std::pow(wgs84_data.first_eccentricity, 2)/4);
double m0_a12 = (std::pow(wgs84_data.first_eccentricity, 4)/64);
double m0_a13 = (std::pow(wgs84_data.first_eccentricity, 6))/256;
double m0 = 1 - m0_a11 - 3*m0_a12 - 5*m0_a13;
// ... additional operation
}
Can anyone shed light on this matter?
One issue is that you're using uninitialized variables here:
double eastingUtmzone; // uninitialized
double northingUtmzone; // uninitialized
convert.UTM(lat, lon, eastingUtmzone, northingUtmzone);
std::cout<< lat << lon<< northingUtmzone<< eastingUtmzone<< std::endl;
So there are at least two points of failure -- within the convert.UTM that uses these variables, and in the std::cout after the call.
Since utilizing uninitialized variables is undefined behavior, expect anything to happen, where one of those things seemingly is a SIGSEGV occurring.
I'm trying to create a memory mapped file using this answer, but I'm getting compile errors. This is my code:
namespace bi = boost::interprocess;
std::string vecFile = "vector.dat";
bi::managed_mapped_file file_vec(bi::open_or_create,vecFile.c_str(), sizeof(struct Rectangle) * data_size);
typedef bi::allocator<struct Rectangle, bi::managed_mapped_file::segment_manager> rect_alloc;
typedef std::vector<struct Rectangle, rect_alloc> MyVec;
MyVec * vecptr = file_vec.find_or_construct<MyVec>("myvector")(file_vec.get_segment_manager());
vecptr->push_back(random_rectangle);
The struct is this:
struct Rectangle{
Rectangle(float *minArr, float *maxArr, int arr, int exp, int ID){
this->arrival = arr;
this->expiry = exp;
this->id = ID;
for(int i=0; i < 2; i++){
min[i] = minArr[i];
max[i] = maxArr[i];
}
int arrival, expiry, id;
float min[2];
float max[2];
}
The error I get is: Compiler could not deduce the template argument for '_Ty*' from 'boost::interprocess::offset_ptr'. What am I doing wrong?
It looks okay to me:
Live On Coliru
#include <boost/interprocess/managed_mapped_file.hpp>
#include <vector>
namespace bi = boost::interprocess;
struct Rectangle {
Rectangle(float *minArr, float *maxArr, int arr, int exp, int ID) {
this->arrival = arr;
this->expiry = exp;
this->id = ID;
for (int i = 0; i < 2; i++) {
min[i] = minArr[i];
max[i] = maxArr[i];
}
};
int arrival, expiry, id;
float min[2];
float max[2];
};
namespace Shared {
using segment = bi::managed_mapped_file;
using mgr = segment::segment_manager;
using alloc = bi::allocator<Rectangle, mgr>;
using vector = std::vector<Rectangle, alloc>;
}
Rectangle random_rectangle() {
float dummy[2] = { };
return { dummy, dummy, 0, 0, 0 };
}
int main() {
#define data_size 10
std::string vecFile = "vector.dat";
Shared::segment mmem(bi::open_or_create, vecFile.c_str(), (10u<<10) + sizeof(struct Rectangle) * data_size);
Shared::vector *vecptr = mmem.find_or_construct<Shared::vector>("myvector")(mmem.get_segment_manager());
vecptr->push_back(random_rectangle());
}
If it doesn't compile exactly as above, please note versions of your library and compiler. Consider upgrading.
I have been trying to use sets as properties for a class. These sets need to be initialized when the class is initialized. I have been trying to use pre-initialized arrays and then set the values of the sets to the contents of the arrays. My problem with this, however, is that it seems like you can only set the contents of a set to the contents of an array when the set is declared which I can't do if it's a class property. I would rather not individually add each piece of the set. Any recommendations? Here's some sample code:
Creature.cpp:
Creature :: Creature()
{
Skill Init[] = {Balance,EscapeArtist,Hide,MoveSilently,OpenLock,Ride,SleightOfHand,Tumble,UseRope};
//DexSkills = ??? (contents of init)
Skill Init[] = {Climb,Jump,Swim};
//StrSkills = ???
Skill Init[] = {Concentration};
//ConSkills = ???
Skill Init[] = {Appraise,Craft,DecipherScript,DisableDevice,Forgery,Knowledge,Psicraft,Search,Spellcraft};
//IntSkills = ???
Skill Init[] = {Autohypnosis,ControlShape,Heal,Listen,Profession,SenseMotive,Spot,Survival};
//WisSkills = ???
Skill Init[] = {Bluff,Diplomacy,Disguise,GatherInformation,HandleAnimal,Intimidate,Perform,UseMagicDevice,UsePsionicDevice};
//ChaSkills = ???
}
and in Creature.h:
#pragma once
#define roll20 (rand()%20) + 1
#define Mod(stat) ((stat-10)/2)
#include <vector>
#include <set>
#include "Global.h"
class Creature
{
protected:
std::set<Skill> DexSkills;
std::set<Skill> StrSkills;
std::set<Skill> ConSkills;
std::set<Skill> IntSkills;
std::set<Skill> WisSkills;
std::set<Skill> ChaSkills;
//static const Skill StrSkills[3];
//static const Skill ConSkills[1];
//static const Skill IntSkills[9];
//static const Skill WisSkills[8];
//static const Skill ChaSkills[9];
const int maxHP;
int HP;
int hitDie;
int speed;
int babBase;
int fortBase;
int refBase;
int willBase;
int AC;
int STR;
int CON;
int DEX;
int INT;
int WIS;
int CHA;
DamageResist DR;
std::vector<Feat> Feats;
Alignment alignment;
//std::set<DamageType> Weaknesses;
//std::set<DamageType> Resistances;
std::set<DamageType> Immunities;
int Resistances [15];
int SkillRanks[40];
public:
//Creature();
int Damage(int damage, DamageType type);
void getDamaged(int damage);
int StatRoll(int stat);
//int StrRoll();
//int ConRoll();
//int DexRoll();
//int IntRoll();
//int WisRoll();
//int ChaRoll();
int SkillCheck(Skill skill);
};
and in my global.h:
typedef enum {
Appraise,Autohypnosis,Balance,Bluff,Climb,Concentration,ControlShape,Craft,DecipherScript,Diplomacy,DisableDevice,Disguise,EscapeArtist,Forgery,
GatherInformation,HandleAnimal,Heal,Hide,Intimidate,Jump,Knowledge,Listen,MoveSilently,OpenLock,Perform,Profession,Psicraft,Ride,Search,SenseMotive,
SleightOfHand,SpeakLanguage,Spellcraft,Spot,Survival,Swim,Tumble,UseMagicDevice,UsePsionicDevice,UseRope
} Skill;
If you are looking for a simple way to copy a C array into a set, you can try something like this:
#include <iterator>
...
int a[] = { 1, 2, 3, 4, 5, 6 };
int n = sizeof(a) / sizeof(a[0]);
std::set<int> s;
std::copy(a, a + n, std::inserter(s, s.end()));