Hello once again everyone, my previous problem appears to be resolved right now thanks for everyone who has helped.

I have to make the following derived class

Your LField class is derived from your Field class and represents a line field.

Upon instantiation, an LField object receives between three and five values, in the following order:

* required:
o an int holding the row number on which the line field is positioned,
o an int holding the column number at which the line field begins,
o an int holding the width of the line field,
* optional:
o a char string holding the initial value of the line field, and
o a bool holding the editability flag for the line field: true for editable, false for not editable.

Your design does not impose any limit on the width of the line field.

If the calling function specifies the first three parameters only, your LField object holds an empty string and is editable. If the calling function specifies the first four parameters only, your object is editable.

If the calling function specifies invalid coordinates, your object uses the closest on-screen coordinates to those specified. If the width is too long for the line field to fit on a screen, your object reduces the width so that the contracted field does fit on the screen. If the initial value occupies more than the field width, your object uses only as many characters of the initial value as will fit within the specified, and if necessary, contracted width.

Your LField class has the following public member functions:

* void display() - causes the line field to be displayed. On systems where terminal output is buffered, your function does not flush the screen buffer. If the field's current value is shorter than the field width, your function fills the right end of the field with trailing spaces. (Such trailing spaces are however not part of the data of the field itself).
* int edit() displays the line field and then, if the field is editable, lets the user edit the field. Your function returns the key code used to terminate editing. The first time a caller calls your function, it positions the cursor at the beginning of the field. Every subsequent time that the caller calls your function, it initially positions the cursor where it was at the end of the previous call, unless the string is now too small, in which case your function positions the cursor just past the end of the string.
Where the field is not editable, your function returns 0 without waiting for any user input.
* bool editable() const returns true if the field is editable, false if it is display-only.
* void *data() returns the address of the string currently stored by the field. In classes derived from LField, this address may be the address of some other type of data being edited.
* Field *clone() const dynamically allocates a separate instance of an LField, making the new instance a copy of the current LField object, and returns the address of the copy. If your function cannot allocate space for a separate instance, your function returns NULL.
It is the calling function's responsibility to deallocate the memory allocated for this copy.
(This function enables the calling function to make a copy of an instance of a class derived from LField without limiting the copy to being a duplicate of the base class object.)

Since your LField class requires dynamic memory allocation to admit field widths without limitation, your class includes a copy constructor, an assignment operator and a virtual destructor.

I apologize for the lengthy text above I just want to show what it is that I have to do exactly.

This is what I have for my header file:

class LField : public Field{
    int row_loc, col_loc, width_tot, index;
    char *initval;
    bool edib;
    
    public:
        LField(int row, int col, int width);
        LField(int row, int col, int width, char *s);
        LField(int row, int col, int width, char *s, bool editable);
        void initialize(int r, int c, int w, bool e);
        ~LField();
        void display();
        int edit();
        bool editable() const;
        void *data();
        Field *clone() const;
        LField& operator = (const LField & rhs);
        LField(const LField & source );
}

and this is what I have in my cpp file:

LField::LField(int row, int col, int width){
    //Checks for valid coords
    if(row < 0){
        row = 0;
    }
    if(row > dtioRows()){
        row = dtioRows() - 1;
    }
    if(col < 0){
        col = 0;
    }
    if(col > dtioColumns()){
        col = dtioColumns() - 1;
    }
    //Checks for width and location
    if((col + width) > dtioColumns()){
        width = width - ((col + width) - dtioColumns());
    }
    
    initialize(row, col, width, true);
    initval = NULL;
}
LField::LField(int row, int col, int width, char *s){
    //Checks for valid coords
    if(row < 0){
        row = 0;
    }
    if(row > dtioRows()){
        row = dtioRows() - 1;
    }
    if(col < 0){
        col = 0;
    }
    if(col > dtioColumns()){
        col = dtioColumns() - 1;
    }
    //Checks for width and location
    if((col + width) > dtioColumns()){
        width = width - ((col + width) - dtioColumns());
    }
    initialize(row, col, width, true);
    if(strlen(s) > width){
        initval = new char[width];
        for(int i = 0; i < width; i++){
            initval[i] = s[i];
        }
    }
    else{
        initval = new char[strlen(s) + 1];
        strcpy(initval, s);
    }
}
LField::LField(int row, int col, int width, char *s, bool editable){
    //Checks for valid coords
    if(row < 0){
        row = 0;
    }
    if(row > dtioRows()){
        row = dtioRows() - 1;
    }
    if(col < 0){
        col = 0;
    }
    if(col > dtioColumns()){
        col = dtioColumns() - 1;
    }
    //Checks for width and location
    if((col + width) > dtioColumns()){
        width = width - ((col + width) - dtioColumns());
    }
    initialize(row, col, width, editable);
    if(strlen(s) > width){
        initval = new char[width];
        for(int i = 0; i < width; i++){
            initval[i] = s[i];
        }
    }
    else{
        initval = new char[strlen(s) + 1];
        strcpy(initval, s);
    }
}
//Function that initializes LField
void LField::initialize(int r, int c, int w, bool e){
    row_loc = r;
    col_loc = c;
    width_tot = w;
    edib = e;
    index = 0;
}
LField& LField::operator = (const LField & rhs){
    if(&rhs != this){
       delete [] initval;
       initval = new char[strlen(&rhs.initval) + 1]
       strcpy(initval, &rhs.initval);
       initialize(&rhs.row_loc, &rhs.col_loc, &rhs.width_tot, &rhs.edib);
    }
    return *this;
}
LField::LField(const LField & source){
       delete [] initval;
       initval = new char[strlen(&source.initval) + 1]
       strcpy(initval, &source.initval);
       initialize(&source.row_loc, &source.col_loc, &source.width_tot, &source.edib);
}
void LField::display(){
    dtioDisplay(initval, row_loc, col_loc, width_tot);
}
int LField::edit(){
    int retval = 0;
    if(edib){
        retval = dtioEdit(initval, row_loc, col_loc, with_tot, &index);
    }
    else{
        dtioDisplay(initval, row_loc, col_loc, width_tot);
        retval = 0        
    }
    return retval;
}
bool LField::editable const(){
    return edib;
}
void *LField::data(){
    return &initval;
}
void *Field::clone() const{
    
}

Once again I am sorry for the length of the post. I would like to know if I am on the right path with what I am doing and if there is anything that I should change or correct. Any input is greatly appreciated. :)

Recommended Answers

All 4 Replies

To judge from appearances:
1. The class destructor is not virtual (see requirements)
2. The class constructors do not pass parameters to the parent class (why?). It's interesting to look at the parent class declaration too...
3. No need in public initialize() member function, make it private (or protected). You have the same check parameters sequences in all constructors. May be better move these codes in initialize() or (more better) use default arguments to declare one and only one constructor:

LField(int row, int col, int width, char *s = 0, bool editable = 0);

4. Some misprintings (for example, in the line #120).
5. Max row check is wrong (must be >= ).
6. Style: better place all privates in the bottom of class declaration with explicit private keyword. Always declare one member per line.

Ok here is my parent class and the derived class:

class Field{
    public:
    virtual void display() = 0;
    virtual int edit() = 0;
    virtual bool editable() const = 0;
    virtual void *data() = 0;
    virtual Field *clone() const = 0;
};
class LField : public Field{
    int row_loc;
    int col_loc;
    int width_tot; 
    int index;
    char *initval;
    bool edib;
    
    public:
        LField(int row, int col, int width);
        LField(int row, int col, int width, char *s);
        LField(int row, int col, int width, char *s, bool editable);
        void initialize(int r, int c, int w, bool e);
        ~LField();
        void display();
        int edit();
        bool editable() const;
        void *data();
        Field *clone() const;
        LField& operator = (const LField & rhs);
        LField(const LField & source );
};

Here is my current cpp file:

#include <string>
#include <iostream>
#include <new>
using namespace std;

#include "screen.h"

//LField class functions
//Different intiailization calls
LField::LField(int row, int col, int width){
    //Checks for valid coords
    if(row < 0){
        row = 0;
    }
    if(row >= dtioRows()){
        row = dtioRows() - 1;
    }
    if(col < 0){
        col = 0;
    }
    if(col > dtioColumns()){
        col = dtioColumns() - 1;
    }
    //Checks for width and location
    if((col + width) > dtioColumns()){
        width = width - ((col + width) - dtioColumns());
    }
    
    initialize(row, col, width, true);
    initval = NULL;
}
LField::LField(int row, int col, int width, char *s){
    //Checks for valid coords
    if(row < 0){
        row = 0;
    }
    if(row >= dtioRows()){
        row = dtioRows() - 1;
    }
    if(col < 0){
        col = 0;
    }
    if(col > dtioColumns()){
        col = dtioColumns() - 1;
    }
    //Checks for width and location
    if((col + width) > dtioColumns()){
        width = width - ((col + width) - dtioColumns());
    }
    initialize(row, col, width, true);
    if(strlen(s) > width){
        initval = new char[width];
        for(int i = 0; i < width; i++){
            initval[i] = s[i];
        }
    }
    else{
        initval = new char[strlen(s) + 1];
        strcpy(initval, s);
    }
    
}
LField::LField(int row, int col, int width, char *s, bool editable){
    //Checks for valid coords
    if(row < 0){
        row = 0;
    }
    if(row >= dtioRows()){
        row = dtioRows() - 1;
    }
    if(col < 0){
        col = 0;
    }
    if(col > dtioColumns()){
        col = dtioColumns() - 1;
    }
    //Checks for width and location
    if((col + width) > dtioColumns()){
        width = width - ((col + width) - dtioColumns());
    }
    initialize(row, col, width, editable);
    if(strlen(s) > width){
        initval = new char[width];
        for(int i = 0; i < width; i++){
            initval[i] = s[i];
        }
    }
    else{
        initval = new char[strlen(s) + 1];
        strcpy(initval, s);
    }
}
//Function that initializes LField
void LField::initialize(int r, int c, int w, bool e){
    row_loc = r;
    col_loc = c;
    width_tot = w;
    edib = e;
    index = 0;
}
LField& LField::operator = (const LField & rhs){
    if(&rhs != this){
       delete [] initval;
       initval = new char[strlen(rhs.initval) + 1];
       strcpy(initval, rhs.initval);
       initialize(rhs.row_loc, rhs.col_loc, rhs.width_tot, rhs.edib);
    }
    return *this;
}
LField::LField(const LField & source){
       delete [] initval;
       initval = new char[strlen(source.initval) + 1];
       strcpy(initval, source.initval);
       initialize(source.row_loc, source.row_loc, source.width_tot, source.edib);
}
void LField::display(){
    dtioDisplay(initval, row_loc, col_loc, width_tot);
}
int LField::edit(){
    int retval = 0;
    if(edib){
        retval = dtioEdit(initval, row_loc, col_loc, width_tot, &index);
    }
    else{
        dtioDisplay(initval, row_loc, col_loc, width_tot);
        retval = 0;        
    }
    return retval;
}
bool LField::editable() const{
    return edib;
}
void *LField::data(){
    return &initval;
}
Field *LField::clone() const{
    
}

I am not sure as to how to make the clone function if you can point me in the right direction that would be great.

Also how would i go about making a single constructor if you can show me that would be really appreciated.

Aha, it's natural that the parent is an abstract class so no need to pass him any parameters. Slightly clumsy interface, usual way to declare such interfaces is:

class Field {
public:
    virtual ~Field() {} // sic! Add null virtual destructor    
    virtual void display() = 0;
    virtual int edit() = 0;
    virtual bool editable() const = 0;
    virtual void *data() = 0;
    virtual Field *clone() const = 0;
};

About clone: it's so simple:

return new LField(*this); // You have copy constructor!

About three in one: there was misprinting in my post above, copy/past then implement the constructor:

LField(int row, int col, int width, char *s = 0, bool editable = true);

There are tons of links about default arguments in C++ functions. For example (randomly selected):
http://msdn.microsoft.com/en-us/library/91563f79(VS.80).aspx
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc07cplr237.htm
You can write:

LField(1,2,3)           //  LField(1,2,3,0,true) called
LField(1,2,3,"Ooh")  //  LField(1,2,3,"Ooh",true) called
LField(1,2,3,"Zoo",false) //

That's all. I'm off-line now...
Good luck!

OK thanks for the help! I got that default thing working too.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.