Archive

Posts Tagged ‘CPP’

Classic Sample: Customer -> Order -> OrderLine in C++

June 8, 2010 1 comment

Hi all,
I have been without internet for a week so no posts. I want some feed back on whether this is good c++ design. There is a little bit of value semantics in places and am keen for some comments.

Blair…

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

class Address{
private:
    string _street;
    string _postcode;
    string _suburb;
    string _state;
    string _country;
public:
    Address();
    Address(string street, string postcode, string suburb, string state, string country);
    void ChangeAddress(string street, string postcode, string suburb, string state, string country);
    string ToString() const;
};

Address::Address(){
}

Address::Address(string street, string postcode, string suburb, string state, string country)
    : _street(street), _postcode(postcode), _suburb(suburb), _state(state), _country(country)
{
}

void Address::ChangeAddress(string street, string postcode, string suburb, string state, string country){
    this->_street = street;
    this->_postcode = postcode;
    this->_suburb = suburb;
    this->_state = state;
    this->_country = country;
}

string Address::ToString() const{
    return "Street: " + _street + " PostalCode: " + _postcode + " Suburb: " + _suburb + " State: " + _state + " Country: " + _country;
}

class Customer{
private:
    int _id;
    string _name;
    Address _address;
public:
    Customer();
    Customer(int id, string name, string street, string postcode, string suburb, string state, string country);
    Customer(const Customer& customer);
    void ChangeAddress(string street, string postcode, string suburb, string state, string country);
    Address GetCurrentAddress() const;
    string GetName() const;
    int GetId() const;
    void Print() const;
};

Customer::Customer(){
}

Customer::Customer(int id, string name, string street, string postcode, string suburb, string state, string country)
    : _id(id), _name(name), _address(Address(street,postcode,suburb,state,country))
{
}

Customer::Customer(const Customer &customer){
    this->_id = customer.GetId();
    this->_name = customer.GetName();
}

void Customer::ChangeAddress(string street, string postcode, string suburb, string state, string country){
    this->_address = Address(street,postcode,suburb,state,country);
}

Address Customer::GetCurrentAddress() const{
    return this->_address;
}

string Customer::GetName() const{
    return this->_name;
}

int Customer::GetId() const{
    return this->_id;
}

void Customer::Print()  const{
    cout << "Id: " << this->_id << " Name: " << _address.ToString() << endl;
}

class OrderLine{
private:
    int _id;
    double _unitcost;
    double _unitprice;
    int _quantity;
    string _productcode;
    string _productdescription;
public:
    OrderLine();
    OrderLine(int id, double unitcost, double unitprice, int quantity, string productcode, string productdrescription);
    void ChangeQuantity(int quantity);
    double GetLineMargin() const;
    double GetLineCost() const;
    double GetLinePrice() const;
};

OrderLine::OrderLine(){
}

OrderLine::OrderLine(int id, double unitcost, double unitprice, int quantity, string productcode, string productdescription)
    : _id(id), _unitcost(unitcost), _unitprice(unitprice), _quantity(quantity), _productcode(productcode), _productdescription(productdescription){
}

void OrderLine::ChangeQuantity(int quantity){
    this->_quantity = quantity;
}

double OrderLine::GetLineCost() const{
    return this->_quantity * this->_unitcost;
}

double OrderLine::GetLinePrice() const{
    return this->_quantity * this->_unitprice;
}

double OrderLine::GetLineMargin() const{
    return this->GetLinePrice() - this->GetLineCost();
}

class Order{
private:
    int _id;
    string _suppliername;
    Customer _customer;
    vector<OrderLine> _orderLines;
public:
    Order();
    Order(int id, string suppliername);
    Order(int id, string suppliername, const Customer& customer);
    int GetId() const;
    const Customer& GetCustomer() const;
    string GetSupplierName() const;
    void ChangeCustomer(const Customer& customer);
    void ChangeSupplier(const string& suppliername);
    void AddLine(const OrderLine& line);
    double GetTotalMargin() const;
    int LineCount() const;
};

Order::Order(){

}

Order::Order(int id, string suppliername)
    : _id(id), _suppliername(suppliername){

}

Order::Order(int id, string suppliername, const Customer &customer)
        : _id(id), _suppliername(suppliername), _customer(customer){

}

int Order::GetId() const{
    return this->_id;
}

string Order::GetSupplierName() const{
    return this->_suppliername;
}

const Customer& Order::GetCustomer() const{
    return this->_customer;
}

void Order::ChangeCustomer(const Customer &customer){
    this->_customer = customer;
}

void Order::ChangeSupplier(const string &suppliername){
    this->_suppliername = suppliername;
}

void Order::AddLine(const OrderLine &line){
    this->_orderLines.push_back(line);
}

double Order::GetTotalMargin() const{
    double total = 0;
    for(vector<OrderLine>::const_iterator i = this->_orderLines.begin(); i != this->_orderLines.end(); i++){
        total += (*i).GetLineMargin();
    }
    return total;
}

int Order::LineCount() const{
    return this->_orderLines.size();
}


int main(int argc, char *argv[])
{

    Customer* customer = new Customer(1,"Blair","Unit 26 / 4 Comer St","6152","Como","WA","Australia");
    customer->Print();

    Address address = customer->GetCurrentAddress();
    address.ChangeAddress("27 Test Street","6029","Perth","NSW","Australia");

    customer->Print();

    customer->ChangeAddress("27 Test Street","6029","Perth","NSW","Australia");
    customer->Print();

    Order order = Order(1,"Bunnings",*customer);
    OrderLine l1 = OrderLine(1,22,33,2,"XYZ","Test");
    OrderLine l2 = OrderLine(1,33,55,3,"XYZ","Test");
    OrderLine l3 = OrderLine(1,44,66,4,"XYZ","Test");

    order.AddLine(l1);
    order.AddLine(l2);
    order.AddLine(l3);

    cout << "Margin: " << order.GetTotalMargin() << " Lines: " << order.LineCount() << endl;

    delete customer;
    return 0;
}

Advertisements
Categories: Development Tags: , ,

Using syslog on Mac OS X in C/C++

May 30, 2010 Leave a comment

Just posting some code on how to write to the syslog in unix. Maybe the title of the post is mis-leading as this should work on all unix based systems. I guess I am just doing it on OS X.

#include <syslog.h>
#include <iostream>
#include <string>
using namespace std;

void writeMessageToSyslogd(const char* message);

int main(int argc, char *argv[])
{
    writeMessageToSyslogd("Blair is writing to syslog");
    return 0;
}

void writeMessageToSyslogd(const char* message){
    openlog("Demo",LOG_CONS,LOG_USER);
    syslog(LOG_ERR,message);
    closelog();
}

Blair…

Categories: Development Tags: , , , , ,

C++ Linked List

May 30, 2010 Leave a comment

This took me a while to get working as I am no expert yet at C++ programming. But now that I have sucessfully put it together I feel my C++ skills are progressing.
A few quick notes this is not a generic list. It only works for integers and at some later point I will change it to support generics.

#include <iostream>

using namespace std;

class Node{
private:
    int value;
    Node* next;
public:
    friend class List;
    Node();
    void setValue(int value);
    int getValue() const;
};

Node::Node(){
    value = 0;
    next = 0;
}

void Node::setValue(int value){
    this->value = value;
}

int Node::getValue() const{
    return this->value;
}

class List{
private:
    int totalitems;
    Node* head;
    Node* tail;
public:
    List();
    ~List();
    void addValue(int value);
    void addStart(int value);
    void print();
    int count();
};

List::List(){
    totalitems = 0;
    head = 0;
    tail = 0;
}

List::~List(){

    Node* current = head;
    while(current != 0){
        Node* temp = current->next;
        delete current;
        current = temp;
    }

}

void List::addValue(int value){
    Node* node = new Node();
    node->setValue(value);
    ++totalitems;


    if(head == 0){
        head = node;
        tail = node;
        return;
    }

    tail->next = node;
    tail = tail->next;

}

void List::addStart(int value){
    Node* node = new Node();
    node->setValue(value);
    ++totalitems;

    if(head == 0){
        head = node;
        tail = node;
        return;
    }

    Node* temp = head;
    head = node;
    head->next = temp;

}

void List::print(){

    Node* start = head;

    while(start != 0){
        cout << start->getValue() << endl;
        start = start->next;
    }

}

int List::count(){
    return totalitems;
}

int main(){

    List list = List();
    list.addValue(1);
    list.addValue(2);
    list.addValue(3);
    list.addValue(4);
    list.addValue(5);
    list.addValue(6);
    list.addValue(7);
    list.addStart(10);

    cout << list.count() << endl << endl;

    list.print();
    return 0;
}

cout Blair 🙂

C++ Exceptions

May 27, 2010 Leave a comment

So I am going to post a pretty well know example in programming on the classic divide by zero issue.

#include <iostream>
#include <string>

using namespace std;

class DivideZeroException{
private:
    string message;
public:
    DivideZeroException(const string& message);
    string getMessage() const;

};

DivideZeroException::DivideZeroException(const string &message){
    this->message = message;
}

string DivideZeroException::getMessage() const{
    return this->getMessage();
}

class Math{
public:
    static double Divide(double number, double divisor);
};

double Math::Divide(double number, double divisor){
    if(divisor == 0)
        throw DivideZeroException("You can not divide by zero");
    return number / divisor;
}

int main(){

    int number = 10;
    int divisor = 0;

    try{

        double result = Math::Divide(number,divisor);
        cout << "Result: " << result << endl;

    }catch(DivideZeroException& exception){
        cout << exception.getMessage() << endl;
    }

    return 0;
}

You can see that we throw an exception when the divisor == 0 and catch it in the calling code. The golden rule in C++ exception handling vs C# is that you throw by value and catch by reference. Why? When the stack is unwinding if you use a reference to a stack variable it will not be able to be referenced and if you throw by pointer then you have to deallocate memory in the catch blocks.

Blair..

Removing Constness

May 24, 2010 Leave a comment

If you have a function that takes a pointer to a datatype and need to pass it a const pointer it wont work. You need to remove the constness of the variable before you pass it in.
i.e.

#include <iostream>
#include <string>

using namespace std;

void print(string* ptr){
    cout << *ptr << endl;
}

int main(int argc, char *argv[])
{

    const string name = "Blair Davidson";
    const string* nptr = &name;
    cout << *nptr << endl;
    print(const_cast<string*>(nptr));

    return 0;
}
Categories: Development Tags: , ,

C# Delegates in C++ using Function Pointers

May 23, 2010 Leave a comment

Well we are back again with just a short and simple post. In C# you can declare a delegate using the delegate keyword. An example might be if we want to check if a student matches some criteria.
i.ie delegate void StudentMatch(Student student);

The above stament declares a delegate aka function pointer with a return type of bool and takes a parameter of student.
This allows us to create a method on the on some other entity that may take a student and a studentmatch delegate and can anser any question about wether a student is valid. The main use of delegates or function pointers is to provide extension points in our code so it perform operations that were not thought of at that point in time. We could use plain OO to achieve this but it is more work in some cases.

In C++ we have function pointers. Here is some code showing you the syntax of declaring the same snippet.

struct Student{
    int* id;
};

bool studentHasIdGreaterThanZero(Student& student);
void printMatchesPredicate(bool (*fp)(Student&), Student& student);

void printMatchesPredicate(bool (*fp)(Student&), Student& student){
    if(fp(student)){
        cout << "We have a match" << endl;
    }
}

bool studentHasIdGreaterThanZero(Student& student){
    return *(student.id) > 0;
}

As you can see we invoke the function pointer just as with C# using normal method invokation syntax.
bool (*fp)(Student&) declare the function pointer. not as nice as C# but achieves the same effect.

Blair..

Categories: Development Tags: , , , , ,

C++ Multiple Inheritance Examples and Issues

May 23, 2010 Leave a comment

Diving straight in with some code…

#include <iostream>
#include <string>
#include <typeinfo>

using namespace std;

class Dog{
public:
    void Bark();
};

class Bird{
public:
    void Chirp();
};

void Dog::Bark(){
    cout << "Bark" << endl;
}

void Bird::Chirp(){
    cout << "Chirp" << endl;
}

class DogBird : public Dog, public Bird{

};

class B1{
public:
    virtual void Print();
};

class B2{
public:
    virtual void Print();
};

void B1::Print(){
    cout << "B1 Print" << endl;
}

void B2::Print(){
    cout << "B1 Print" << endl;
}

class B3 : public B1, public B2{

};

int main(int argc, char *argv[])
{
    DogBird* c = new DogBird();
    c->Bark();
    c->Chirp();
    delete c;

    B3* b = new B3();
    b->B1::Print();
}

You can see two class Dog and Bird declared initially. Then DogBird inherits from both. The we can see both the bark and chirp methods are available in the derived class DogBird. Pretty easy.
So were the pain come in is when both parent classes have a method with the same name, see the B1 and B3 classes. We B3 inherits this and you call print which one should it choose?? The compiler only get un happy when you actually make a call to this which can also be a trap. If you see the b->B1::Print() statement this means use the print from B! class. This is horrible.

Rule of thumb if you own the classes i.e you wrote them change the names so there distinct, much easier and less error prone, otherwise if its a third party class, live with it.

Blair..

Categories: Development Tags: , , ,