I have a very strange problem now.
class Message
{
Field time;
void SetTimeStamp()
{
time.dataTimeValue = &boost::posix_time::microsec_clock::universal_time();
}
void SetOtherFields()
{
}
};
class Field
{
boost::posix::ptime* dateTimeValue;
};
int main()
{
Message myMessage;
myMessage.SetTimeStamp();
myMessage.SetOtherFields();
}
When I call myMessage.SetTimeStamp(), I can set the TimeStamp correctly, I can see the address of dateTimeValue and the Value makes sense. But after that, I call myMessage.SetOtherFields(), the dateTimeValue pointer still points to the same memory which is good, but the value in that memory changes to a carzy number. I don't know what happened.
A decent compiler should have warned that the code is taking address of temporary. The microsec_clock::local_time() function returns ptime by value, resulting in Message::SetTimeStamp storing the address of the temporary into Field::dateTimeValue. Trying to access the values of the memory will result in undefined behavior.
To resolve this, consider changing Field to aggregate a boost::posix::ptime member variable, rather than a pointer.
class Field
{
public:
boost::posix_time::ptime dateTimeValue;
};
class Message
{
public:
Field time;
void SetTimeStamp()
{
time.dataTimeValue = boost::posix_time::microsec_clock::universal_time();
}
};
Related
Here's my code:
class Patient {
public:
const int patientId;
const PatientKind kind;
const bool hasInsurance;
std::vector<ProcedureKind> procedures;
Patient(int, PatientKind, bool);
bool addProcedure(const ProcedureKind procedure);
double billing();
virtual double liability() = 0;
};
class Hospital {
public:
Patient &addPatient(const PatientInfo &);
};`
I don't know how to write:
Patient &Hospital::addPatient(const PatientInfo &)
{
}
Whatever I try to return or pass as argument gives me an error... Also, I don't understand what is this function expecting as an argument with just &?
Any kind of help / insight will be appreciated :D
Seems like you're trying to implement a header definition someone else wrote. That & means that the function expects a reference to an instance of PatientInfo. In the implementation, the only thing you have to do is to give the parameter a name like so:
Patient& addPatient(const PatientInfo& info)
{
// do whatever you need with 'info'
}
You can read more about c++ function declaration and implementation in any basic c++ text.
I am designing a solution for an ethereum smart contract that does bidding. The use-case includes reserving a name eg. "myName" and assigning to an address. And then, people can bid for that name (in this case myName). There can be multiple such biddings happening for multiple names.
struct Bid {
address bidOwner;
uint bidAmount;
bytes32 nameEntity;
}
mapping(bytes32 => Bid[]) highestBidder;
So, as you can see above, Bid struct holds data for one bidder, similarly, the key (eg. myName) in the mapping highestBidder points to an array of such bidders.
Now, I am facing a problem when I try to return something like highestBidder[myName].
Apparently, solidity does not support returning an array of structs (dynamic data). I either need to rearchitect my solution or find some workaround to make it work.
If you guys have any concerns regarding the question, please let me know, I will try to make it clear.
I am stuck here any help would be appreciated.
As you mentioned, this is not yet supported in Solidity. The powers that be are planning on changing it so you can, but for now, you have to retrieve the number of elements and then retrieve the decomposed struct as a tuple.
function getBidCount(bytes32 name) public constant returns (uint) {
return highestBidder[name].length;
}
function getBid(bytes32 name, uint index) public constant returns (address, uint, bytes32) {
Bid storage bid = highestBidder[name][index];
return (bid.bidOwner, bid.bidAmount, bid.nameEntity);
}
Edit to address question in comment regarding storage vs memory in this case
Local storage variables are pointers to state variables (which are always in storage). From the Solidity docs:
The type of the local variable x is uint[] storage, but since storage is not dynamically allocated, it has to be assigned from a state variable before it can be used. So no space in storage will be allocated for x, but instead it functions only as an alias for a pre-existing variable in storage.
This is referring to an example where the varable used is uint[] x. Same applies to my code with Bid bid. In other words, no new storage is being created.
In terms of cost:
getBid("foo", 0) using Bid memory bid:
getBid("foo", 0) using Bid storage bid:
In this case, storage is cheaper.
Return an array of struct in solidity?
In below function getBid returns array of bid structure.
contract BidHistory {
struct Bid {
address bidOwner;
uint bidAmount;
bytes32 nameEntity;
}
mapping (uint => Bid) public bids;
uint public bidCount;
constructor() public {
bidCount = 0;
storeBid("address0",0,0);
storeBid("address1",1,1);
}
function storeBid(address memory _bidOwner, uint memory _bidAmount, bytes32 memory _nameEntity) public {
bids[tripcount] = Bid(_bidOwner, _bidAmount,_nameEntity);
bidCount++;
}
//return Array of structure
function getBid() public view returns (Bid[] memory){
Bid[] memory lBids = new Bid[](tripcount);
for (uint i = 0; i < bidCount; i++) {
Bid storage lBid = bids[i];
lBids[i] = lBid;
}
return lBids;
}
}
About "returning an array of structs"... just a small workaround in order to return an array of structs extracted from medium
pragma solidity ^0.4.13;
contract Project
{
struct Person {
address addr;
uint funds;
}
Person[] people;
function getPeople(uint[] indexes)
public
returns (address[], uint[]) {
address[] memory addrs = new address[](indexes.length);
uint[] memory funds = new uint[](indexes.length);
for (uint i = 0; i < indexes.length; i++) {
Person storage person = people[indexes[i]];
addrs[i] = person.addr;
funds[i] = person.funds;
}
return (addrs, funds);
}
}
The uint[] index parameters should contain the indexes that you want to access.
Best
I got 2 classes that represent Player and I want to keep in one of them pointer to another one.
So inside my view::Player I create pointer to logic::Player
namespace view {
class Player {
std::shared_ptr<logic::Player> m_player;
//logic::Player* m_player;
public:
void create(logic::Player& player) {
m_player = std::make_shared<logic::Player>(player);
//m_player = &player;
}
};
}
view::Player is created in view::GameState and simply initialised like this
m_playerOneView.create(m_game.getActivePlayer());
m_game is logic::Game object
logic::Game has std::vector<logic::Player>, and public method that returns active one
logic::Player& logic::Game::getActivePlayer() {
return m_players[m_activePlayer];
}
And finnaly
namespace logic {
class Player {
std::string m_name;
int position;
};
}
Now I need original object of logic::Player pointed by std::shared_ptr in my view::Player class. I could simply do that by changing that to raw pointer and it works then (2 commented lines do what I want to achieve basicly). But when I try to do this on std::shared_ptr, I seem to work on copy of logic::Player, because when I update his position for example, it changes everywhere in the game but not in view::Player. How to do that using std::shared_ptr then?
Is there a way to use enum default parameters in Haxe? I get this error:
Parameter default value should be constant
enum AnEnum {
A;
B;
C;
}
class Test {
static function main() {
Test.enumNotWorking();
}
static function enumNotWorking(e:AnEnum = AnEnum.A){}
}
Try Haxe link.
Update: this feature has been added in Haxe 4. The code example from the question now compiles as-is with a regular enum.
Previously, this was only possible if you're willing to use enum abstracts (enums at compile time, but a different type at runtime):
#:enum
abstract AnEnum(Int)
{
var A = 1;
var B = 2;
var C = 3;
}
class Test3
{
static function main()
{
nowItWorks();
}
static function nowItWorks(param = AnEnum.A)
{
trace(param);
}
}
There's nothing special about the values I chose, and you could choose another type (string, or a more complex type) if it better suits your use case. You can treat these just like regular enums (for switch statements, etc.) but note that when you trace it at runtime, you'll get "1", not "A".
More information: http://haxe.org/manual/types-abstract-enum.html
Sadly enums can't be used as default values, because in Haxe enums aren't always constant.
This piece of trivia was on the old website but apparently hasn't made it into the new manual yet:
http://old.haxe.org/ref/enums#using-enums-as-default-value-for-parameters
The workaround is to check for a null value at the start of your function:
static function enumNotWorking(?e:AnEnum){
if (e==null) e=AnEnum.A;
}
Alternatively, an Enum Abstract might work for your case.
I have something like this:
enum EFood{
eMeat,
eFruit
};
class Food{
};
class Meat: public Food{
void someMeatFunction();
};
class Fruit: public Food{
void someFruitFunction();
};
class FoodFactory{
vector<Food*> allTheFood;
Food* createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
if(food)
allTheFood.push_back(food);
return food;
}
};
int foo(){
Fruit* fruit = dynamic_cast<Fruit*>(myFoodFactory->createFood(eFruit));
if(fruit)
fruit->someFruitFunction();
}
now I want to change my application to use boost shared_ptr and weak_ptr such that i can delete my food instance in a single place. it would look like this:
class FoodFactory{
vector<shared_ptr<Food> > allTheFood;
weak_ptr<Food> createFood(EFood foodType){
Food* food=NULL;
switch(foodType){
case eMeat:
food = new Meat();
break;
case eFruit:
food = new Fruit();
break;
}
shared_ptr<Food> ptr(food);
allTheFood.push_back(ptr);
return weak_ptr<Food>(ptr);
}
};
int foo(){
weak_ptr<Fruit> fruit = dynamic_cast<weak_ptr<Fruit> >(myFoodFactory->createFood(eFruit));
if(shared_ptr<Fruit> fruitPtr = fruit.lock())
fruitPtr->someFruitFunction();
}
but the problem is that the dynamic_cast doesn't seem to work with weak_ptr
how do I get a weak_ptr<Fruit> out of a weak_ptr<Food> if i know that the object it points to is of derived type?
Direct casting from weak_ptr<A> to weak_ptr<B> will surely don't work, I think you have to convert it to a shared_ptr and then use the casting functionality of shared_ptr:
weak_ptr<Food> food = myFoodFactory->createFood(eFruit)
weak_ptr<Fruit> fruit = weak_ptr<Fruit>(dynamic_pointer_cast<Fruit>(food.lock());
You cannot use dynamic_cast with shared_ptr because it would require to change the template of the object. What in fact you want to do is a dynamic_cast on the internal pointer. To do this you could do a dynamic_cast on the pointer returned by get but that would not be so clean because the reference would not be shared(irrelevant in your case since you're using weak_ptr but relevant when using shared_ptr) and creating a share_ptr on this would be undefined resulting on a double delete.
Use dynamic_pointer_cast to do this but the two types still need to be related. In other words dynamic_cast<T*>(r.get()) needs to be well formed.
you can use BOOST_DISABLE_THREADS to improve performance if you're not bound to multithreading, see https://stackoverflow.com/a/8966130/1067933