0

Okay I need some help with this

I am trying to figure out how to create a copy constructor with this "webLinsks" class object when it is called it is supposed to produce an array of "webLinks" objects from the 'myWeb' array and put it into 'newWeb' a new "webLinks" array as declared on line 281.

webLinks* myWeb = new webLinks[numSites]();

Here is the code for the copy constructor as on line 306:

webLinks* newWeb = new webLinks(myWeb);

then I have to assign the newWeb object to another newNewWeb object as shown on line 324 :

webLinks* newNewWeb = newWeb; // using overloaded = operator

I am unsure if my overloaded operator is working. I am unsure which way to do it. Here my code for it on lines 186-207:

webLinks* webLinks::operator=(webLinks *WL)
{
    // TODO: insert return statement here
    //URL = WL.URL;//.getURL());
    //URL = new String(URL->getWord());
    URL = new String(WL->URL->getWord());
    numLinks = WL->numLinks;
    hyperLinks = WL->getHyperlinks();

    return WL;
}

webLinks& webLinks::operator=(webLinks &WL)
{
    // TODO: insert return statement here
    //URL = WL.URL;//.getURL());
    //URL = new String(URL->getWord());
    URL = new String(WL.URL->getWord());
    numLinks = WL.numLinks;
    hyperLinks = WL.getHyperlinks();

    return WL;
}

My programm input for terminal (txt file): https://drive.google.com/file/d/1HVESZnIhH16RP3FmKHGMCKHLILbuTOb0/view?usp=sharing

My code:

// links.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
using namespace std;

// used to empty a given string A of length n
void emptyString(char* A, int n) {
    for (int i = 0; i < n; i++) {
        A[i] = '\0';
    }
}

// copy a string A to B of length n
void stringCopy(char* A, int n, char* B) {
    for (int i = 0; i < n; i++) {
        B[i] = A[i];
    }
}

// return the length of a given string A
int stringLength(char* A) {
    int size = 0;
    while (A[size] != '\0')
        size++;
    return size; //size is the last index position
}

// get one token from redirected input and return that string (alphanumeric)
char* getNextToken() {
    char* str = new char[25]; //assumes a max token size of 20
    emptyString(str, 25);

    char c;
    int i = 0;
    while (!cin.eof()) {
        cin.get(c);
        if (!cin.eof()) {
            if ((c != '\n') && (c != ' ')) {
                if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '.'))
                    //|| ((c >= '0') && (c <= '9')))
                    str[i++] = c;
            }
            else if ((c == '\n') && (i > 0))
                return str;
            else if ((c == ' ') && (i > 0))
                return str;
        }
    }
    if (i > 0)
        return str;
    else
        return NULL;
}


class String {

    friend ostream& operator << (ostream& oS, String& s);
    protected:
        char *str;
        int size;
    public:
        
        String();
        String(char* C);
        String(String &S);
        ~String();

        int Size();
        char* getWord();


};

ostream& operator<<(ostream& oS, String& s)
{
    // TODO: insert return statement here
    oS << s.str;
    return oS;
}

String::String()
{
    str = new char[5]{ 'N','u','l','l','\0'};
    size = 4;
}

String::String(char* C)
{
    int len = stringLength(C);
    /*str = new char[len];
    for (int i = 0; i < len; i++) {
        str[i] = C[i];
    }
    */
    str = C;
    size = len;
}

String::String(String& S)
{
    str = S.getWord();
    size = S.Size();
}

String::~String()
{
    delete str;
}

int String::Size()
{
    return size;
}

char* String::getWord()
{
    return str;
    //return this->str;
}

class webLinks {

        friend ostream& operator << (ostream& S, webLinks& s);
    protected:
        String* URL;
        int numLinks;
        webLinks** hyperLinks;
        int id = 0;
    public:
        webLinks();
        webLinks(String& x, int n);
        webLinks(webLinks& WL);
        webLinks(webLinks* WL);
        ~webLinks();
        webLinks& operator= (webLinks& WL);
        webLinks* operator= (webLinks* WL);
        webLinks** getHyperlinks();
        String* getURL();
        int getID();

        void setURL(String* S);
        void setURL(char* C);
        void setID(int id);
        void addNeighbor(webLinks& link, int j);
        void setNeighbors(int neighbors);
        void displayIncomingLinks(int numOfLinks);
    };

webLinks::webLinks()
{
    URL = new String();
    numLinks = 0;
    hyperLinks = new webLinks * [0];
}

webLinks::webLinks(String &x, int n)
{
    URL = new String(x);
    numLinks = n;
    hyperLinks = new webLinks * [n];
}

webLinks::webLinks(webLinks& WL)
{
    URL = WL.getURL();
    numLinks = WL.numLinks;
    hyperLinks = WL.getHyperlinks();
}

webLinks::webLinks(webLinks* WL)//int numSites)
{   
    //for (int i = 0; i < numSites; i++) {
        URL = WL->getURL();
        numLinks = WL->numLinks;
        hyperLinks = WL->getHyperlinks();
    //}
}

webLinks::~webLinks()
{
    delete URL;
    delete hyperLinks;
}
webLinks* webLinks::operator=(webLinks *WL)
{
    // TODO: insert return statement here
    //URL = WL.URL;//.getURL());
    //URL = new String(URL->getWord());
    URL = new String(WL->URL->getWord());
    numLinks = WL->numLinks;
    hyperLinks = WL->getHyperlinks();

    return WL;
}
webLinks& webLinks::operator=(webLinks &WL)
{
    // TODO: insert return statement here
    //URL = WL.URL;//.getURL());
    //URL = new String(URL->getWord());
    URL = new String(WL.URL->getWord());
    numLinks = WL.numLinks;
    hyperLinks = WL.getHyperlinks();

    return WL;
}
webLinks** webLinks::getHyperlinks()
{
    return hyperLinks;
}

String* webLinks::getURL()
{
    return URL;
}

void webLinks::setURL(String* S)
{
    URL = new String(S->getWord());
}

void webLinks::setURL(char* C)
{
    URL = new String(C);
}

void webLinks::setID(int ID)
{
    this->id = ID;
}

int webLinks::getID()
{
     return id;
}
void webLinks::addNeighbor(webLinks& link, int j)
{
    hyperLinks[j] = &link;
}
void webLinks::setNeighbors(int numNeighbors)
{
    hyperLinks = new webLinks*[numNeighbors];
}

void webLinks::displayIncomingLinks(int numOfLinks)
{
    int count = 0;
    for (int i = 0; i < 4; i++) {
        cout << hyperLinks[i]->id << endl;
    }
    cout << "\n~~~~~Webpages contained as hyperLinks: \n" << endl;
    for (int i = 0; i < numOfLinks; i++) {
        for (int j = 0; j < hyperLinks[i]->numLinks; j++) {
            if (hyperLinks[j]->id == hyperLinks[i]->id)
                count++;
        }
    }
    cout << URL->getWord() << ": " << count << endl;
    for (int i = 0; i < numLinks; i++) {
        for (int j = 0; j < hyperLinks[i]->numLinks; j++) {
            if (hyperLinks[i]->getURL() == URL)
                cout << "** " << hyperLinks[i]->getURL();
        }
    }
}

int main()
{
    std::cout << "Hello World!\n";

    int numSites;
    int siteNo;
    int numNeighbors = 0;
    int neighbor = 0;
    char* token;

    cin >> numSites;
    cout << "Number of Sites: " << numSites << endl;

    webLinks* myWeb = new webLinks[numSites]();

    for (int i = 0; i < numSites; i++) {
        //read the URL and put it is myWeb[i].setURL (....);
        token = getNextToken();
        /*for (int i = 0; i < 25; i++)
            cout << token[i];
        cout << ": stored. " << endl;*/
        myWeb[i].setURL(token);
        //myWeb[i] = *new webLinks(*new String(token), numSites); //Change: myWeb[i] = new webLinks(new String(token), numSites);

    }



    for (int i = 0; i < numSites; i++) {
        cin >> siteNo >> numNeighbors;
        myWeb[siteNo].setNeighbors(numNeighbors);
        myWeb[siteNo].setID(i);
        for (int j = 0; j < numNeighbors; j++) {
            cin >> neighbor;
            myWeb[siteNo].addNeighbor((myWeb[neighbor]), j); // change: myWeb[siteNo].addNeighbor(&(myWeb[neighbor]), j);
        }
    }

    webLinks* newWeb = new webLinks(myWeb);
    //webLinks* newWeb = new webLinks[numSites](); // using copy constructor
    //for (int j = 0; j < numSites; j++ ) {
    //  newWeb[j] = myWeb[j];
    //}
    newWeb[0].setURL(new char[6]{ 'E','m','p','t','y','\0'});
    // call the overloaded << operator using the newWeb object.

    /*for (int j = 0; j < numSites; j += 3 ) {
        cout << *newWeb[j].getURL() << " " << *newWeb[j+1].getURL() 
            << " " << *newWeb[j+2].getURL() << " " << endl;
    }*/
    

    /*for (int j = 0; j < numSites; j++ ) {
        cout << newWeb[j].getURL() << " : " << *newWeb[j].getURL() << endl;
    }*/

    webLinks* newNewWeb = newWeb; // using overloaded = operator
    // call the displayIncomingLinks() method using the newNewWeb object.
    newNewWeb->displayIncomingLinks(numSites);

    cout << "Done" << endl;
    return 0;

}


  • 1
    `webLinks* newNewWeb = newWeb; // using overloaded = operator` is wrong. It is initialising a pointer `newNewWeb` with the value of the pointer `newWeb`. Raw pointer initialisation (like this) *never* uses an overloaded `operator=()` because it is not possible to overload such an operator for built-in types (including raw pointers to any type). The initialisation or assignment of raw pointers is part of the core language – Peter Mar 26 '21 at 06:01
  • Handy reading: [What is the copy-and-swap idiom?](https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) Note that this isn't the most efficient solution, but it is easy to write and hard to get wrong. While reading it, note the function prototypes. There is no pointer-accepting, pointer-returning version and they take the parameters as `const` references. The `const` reference can come in really handy later. – user4581301 Mar 26 '21 at 06:01
  • What problems are you facing? SO is not made for code reviews, see https://codereview.stackexchange.com if you want one. Here you should ask a specific question about the code you've shown. – Lukas-T Mar 26 '21 at 06:05
  • Avoid allocating `String`s with with `new`. [In general avoid `new`](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) it causes more trouble than it's worth, and there's almost always an easier way to write the code without it. If `String` is written correctly, it observes [the Rule of three or Five](https://en.cppreference.com/w/cpp/language/rule_of_three) so that `WebLinks` doesn't have to and can hopefully stay stupid and observe the Rule of Zero. – user4581301 Mar 26 '21 at 06:08
  • Think extra hard about what happens on this line: `hyperLinks = WL.getHyperlinks();`. Ask yourself how many objects now point to those same hyperlinks? How many objects consider themselves [owners](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) of those hyperlinks. How many times are those hyperlinks going to be `delete`ed? – user4581301 Mar 26 '21 at 06:17

0 Answers0