2

C++/CLI has a System::Object class to serve this purpose, but I can't seem to find one in the standard library. Basically I'm writing a set of classes, and I would like the base class to store a vector of std::stringin a content property, but derived classes might need to store a vector of something else (perhaps even one of my own classes). It might seem like an odd goal, but I'm writing a some file access classes to let me more easily manipulate files of different formats. The base File class will store each line in a string, as part of the vector - but a class for JSON, for instance, might need to store JS-Style collections/objects, etc.

The only way I could think to do this is to have the content property a vector of objects (or some other universal base class - I can derive any custom classes from it for polymorphism's sake too) and then cast it back into whatever type is necessary depending on the type of child object that is being used. I soon discovered that I couldn't find any mention of std::object (or similar) anywhere.

This example should demonstrate what I'm trying to do:

class File {
protected:
    std::vector<std::object> _content;

public:
    //Contructors/methods/etc.

    std::string getItemAt(size_t index) {
        return static_cast<std::string>(this->_content[index]);
    }

    void setItemAt(size_t index, std::string value) {
        this->_content[index] = static_cast<std::object>(value);
    }
};

class JSONFile: File {
public:
    //Constructors/methods/etc.

    SomeObject getItemAt(size_t index) {
        return static_cast<SomeObject>(this->_content[index]);
    }

    void setItemAt(size_t index, SomeObject value) {
        this->_content[index] = static_cast<std::object>(value);
    }
};

Note that this example assumes that std::object exists, and that SomeObject would be whatever is used to handle the JSON (again, for example - this could be anything) data. SomeObject would obviously derive from std::object.

Any suggestions would be greatly appreciated, or if I'm going completely the wrong way about this, any feedback as to how I could do it so that the std::object thing isn't necessary would be greatly appreciated :)

brads3290
  • 1,926
  • 1
  • 14
  • 20

3 Answers3

8

No.

Because C++ is all about "you only pay for what you use".

What would the interface of std::object look like? If there were any member functions, those would have to be virtual to be of any use, resulting in a runtime cost because of dynamic dispatch.

If the hypothetical std::object was an empty class, what could you do with a std::object reference? Not much, since it wouldn't have any member functions to call. Why make everything derive from a single base when they have nothing in common.


If you really need a base for all of your classes, you can always write one. But note that doing so might not be a good design decision.

Community
  • 1
  • 1
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • That's a fair point. Do you know why it is that C++/CLI implements one? – brads3290 Oct 19 '15 at 21:54
  • I like this thought process. I would like to expand that you also want to think about what the storage requirements of the hypothetical std::object would be to store it in a contiguous array. – Landon Oct 19 '15 at 21:55
  • 1
    @BradSullivan: To implement [Common Type System](https://en.wikipedia.org/wiki/Common_Type_System) :) You may find more information at [What's So Common About the Common Type System](http://www.codeguru.com/csharp/.net/net_general/commontypesystemcts/article.php/c4631/Whats-So-Common-About-the-Common-Type-System-CTS.htm) – Landon Oct 19 '15 at 21:58
  • @Landon Being an abstract class (supposedly), you could only store pointers to it in the array. – Emil Laine Oct 19 '15 at 22:03
  • @Landon ahh okay so there's no need for a common type system in standard C++ because it doesn't need to be compatible with other languages. Makes sense :) – brads3290 Oct 19 '15 at 22:04
  • @zenith Yes, which is less than ideal because your array objects are possibly all over memory. – Landon Oct 19 '15 at 22:15
4

Is there a base class from which all members of the C++ standard library derive?

The short answer is "No."
The long answer is "Definitely not."

An answer that provides more details can be seen at a related SO site: Why is base-for-all-objects discouraged in C++.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    Could you elaborate in an "extremely long answer"? It is more useful for me browsing answers to see the "Why not" rather than the absolute answer. – Landon Oct 19 '15 at 21:40
2

When I see you define

std::vector<std::object> _content;

it tells me that your goal is to rather do generic programming with templates than object oriented programming with inheritance. This is the same style of std::vector and co., so it shouldn't look too unfamiliar.

Your code could be:

template <typename FileObject>
class File {
public:
    std::vector<FileObject> _content;

public:
    //Constructors/methods/etc.

    FileObject getItemAt(size_t index) {
        return this->_content[index];
    }

    void setItemAt(size_t index, std::string value) {
        this->_content[index] = FileObject(value);
    }
};

then use it as

json_files = File<JSONObject>();
json_files.setItemAt(1, "{}");

or if you have special operations you want to perform on your json object list, the function can take an explicit File<JSONObject> parameter. It's also possible to inherit from File<JSONObject>, but mixing and matching OO/Generic is discouraged.

Now, closer to your title question: you can't easily store different File types in the same vector, but think about how you would implement that. What are the storage requirements for File<int>? For File<double>? This is a core spot where your OO/inheritance solution will become ungainly and using generic programming makes it impossible to try, which is good.

Landon
  • 180
  • 10
  • Whoops, this comment doesn't actually answer your question about core base class, but rather cutting to the core issue with your interface. – Landon Oct 19 '15 at 21:32
  • That's actually great - thanks! I did ask for suggestions too so this answer is definitely a valid one. – brads3290 Oct 19 '15 at 21:57
  • Thank you. I wonder why it was flooded with downvotes after posting. – Landon Oct 19 '15 at 22:01
  • This doesn't quite have the same functionality as a common base class; the template parameter must be known at compile-time. – M.M Oct 19 '15 at 22:02
  • In his use case, he already knew the type at compile time by virtue of wanting a JSONFile. Generally though, you are correct. – Landon Oct 19 '15 at 22:13
  • @BradSullivan If you don't mind, check out the last few paragraphs of my answer again. I didn't check that `File` was rendered correctly and it might have been extra confusing. – Landon Oct 19 '15 at 22:23
  • @Landon I think I get what you mean, though ideally I don't think I would need a File etc. because the _contents property is only storing sections of the file - in the base File class, it happens to be broken up by lines but other derivatives of that class might break it up differently. Were I to store a File of ints I would likely extract them as strings anyway and convert them only when necessary. – brads3290 Oct 20 '15 at 00:23
  • Right, those were just hypothetical cases as types you might be able to more easily reason about storage requirements. – Landon Oct 20 '15 at 01:35