Home > OS >  C : Call constructor of object inside of a vector
C : Call constructor of object inside of a vector

Time:11-09

I can't seem to find an answer to my question. Everything I've read on the matter seems to not quite connect and I'm starting to think what I want is impossible.

I'm working on a very very very light database management system, it's a college project and in my group I'm tasked with the main functions. Here's my problem:

We will run the project as project.exe commands1.txt commands2.txt commands3.txt for example. Now, I have to create a std::vector containing objects of the "File" class so they can be used later by my colleagues doing the parsing. This is the class code (not finished, still working on)

class File {
    protected:
        std::string name;
        std::fstream file;

    public: 
        File() {}

        File( // TO ADD REGEX
            std::string name
        ) {
            if (name != "")
                this->name = name;
            if (name != "" && !this->file) 
                this->file.open(consts::path   name);

        }       

        ~File(
        ) {
            this->name = "";
            if (this->file)
                this->file.close();
        }

        std::string getName(
        ) {
            return this->name;
        }

        void setName(
            std::string name
        ) {
            if (name != "") // TO ADD REGEX
                this->name = name;
        }

        std::fstream* getFile(
        ) {
            return &(this->file);
        }

        bool getStatus(
        ) {
            if (this->file)
                return true;
            else
                return false;
        }

    };

Also my main:

int main(
    int argc,
    char* argv[]
) {
    
    std::string current_exec_name = argv[0];
    std::vector<std::string> all_args;
    all_args.assign(argv, argv   argc);
    
    std::vector<Files::File> commands = new // ???
}

How do I create a vector with n objects of the class File, so that each one is ran with the constructor File( std::string name ), with name being the equivalent argument in argv[ ]?

Read everywhere that you can initialize them like (C FAQ)

class Fred {
public:
  Fred(int i, int j);      ← assume there is no default constructor
  ...
};

int main()
{
  Fred a[10] = {
    Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7),  // The 10 Fred objects are
    Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7)   // initialized using Fred(5,7)
  };
  ...
}

but I can't use this style since I don't know how many commands (.txts) will be sent.

CodePudding user response:

Simply use a loop, calling the vector's push_back() or emplace_back() method on each iteration, eg:

int main(int argc, char* argv[]) {
    
    std::string current_exec_name = argv[0];
    std::vector<std::string> all_args;
    all_args.assign(argv, argv   argc);
    
    std::vector<Files::File> commands;
    commands.reserve(all_args.size());

    for (auto &arg : all_args) {
        commands.push_back(Files::File(arg));
        // or:
        commands.emplace_back(arg);
    }
} 

CodePudding user response:

I suppose the simplest approach is to just tell the compiler to construct your vector from a range. You could even use (almost) the same range you used to assign values to all_args. For example:

#include <iostream>
#include <string>
#include <vector>

class File {
  public:
    File(std::string name) {
        std::cout << "File: " << name << "\n"; // To confirm each construction
    }
};

int main(int argc, char* argv[])
{
    std::vector<File> commands(argv   (argc > 0 ? 1 : 0), argv   argc);
}

This says that commands is to be constructed from a range. Each element (each char*) from argv 1 to argv argc is used to construct an element of commands. (The weird expression (argc > 0 ? 1 : 0) is to handle the case where no arguments were provided.) Since char* implicitly converts to std::string, the constructor taking a std::string is used.

I did tweak the range to exclude the first argument. I suspect you do not want to construct a File based on the name of your program (what you stored in current_exec_name), but you could always drop the " weird expression" if my suspicion is wrong.


Since you did some digging around, here's a bonus reference for you: the vector constructors; I used #5.

  • Related