answersLogoWhite

0

📱

C++ Programming

Questions related to the C++ Computer Programming Language. This ranges all the way from K&R C to the most recent ANSI incarnations of C++, including advanced topics such as Object Oriented Design and Programming, Standard Template Library, and Exceptions. C++ has become one of the most popular languages today, and has been used to write all sort of things for nearly all of the modern operating systems and applications." It it a good compromise between speed, advanced power, and complexity.

2,546 Questions

How can template increase the code reusebility in c plus plus?

Templates encourage generic programming. When classes or functions only differ by type, there is no need to write the same implementations over and over -- the compiler generates the functions or classes from the template. You can also cater for specialisation, so if you need a more specific implementation for pointers to types rather than actual types, you can provide the code to cater for this, without the need to duplicate already existing code that caters for all types.

What is object oriented programming language in C plus plus?

Core PrinciplesSeparation of ConcernsA given problem that involves different kinds of concerns should be identified and separated to cope with complexity, and to achieve the required factors of robustness, adaptability, maintainability, and reusability Single Responsibility PrincipleEach responsibility should be a separate class, because each responsibility is an axis of change CohesionThe degree to which its responsibilities form a meaningful unit; higher cohesion is better Interface Segregation PrincipleThe dependency of one class to another one should depend on the smallest possible interface Dependency Inversion PrincipleThe modules that implement a high level policy should not depend on the modules that implement the low level policies, but rather, they should depend on some well-defined interfaces

C program to print number in reverse order?

#include<stdio.h>

#include<conio.h>

void main()

{

clrscr();

int r=0,d,m,n;

printf("Enter a value=");

scanf("%d",&n);

m=n;

do

{

d=m%10;

m=m/10;

r=(r*10)+d;

}

while(m!=0);

printf("%d is the reverse",r);

getch();

}

How cold boot different a warm boot?

A cold boot always begins with the power off whereas a warm boot does not interrupt the power supply. Although there may not appear to be any difference on the surface (a POST is performed regardless), a cold boot is more reliable as it ensures all hardware is properly reset.

When diagnosing hardware issues, it's always best to cold boot the system to ensure consistency. It's also best to let the system rest for at least 30 seconds to allow any residual current to drain before powering up again. Ideally, external peripherals (USB drives, printers, domestic routers, etc) should be turned off as well. Hardware issues are problematic enough without increasing the number of variables you have to contend with.

C plus plus program to accept a string from user and count number of vowels in the string using pointer to string?

#include

#include

void main()

{ char str[50];

int i,count,countc;

printf("Enter a string : ");

gets(str);

count=0;

i=0;

while(str[i]!='\0′)

{ if(str[i]==' ')

count++;

i++;

}

printf("The total number of words are %d ",count+1);

}

Read more: http://programmingkid.com/count-number-of-words-in-a-string/#ixzz1aGIR1odb

Write a c program to compare two strings without using builtin function?

A string is a character array, so you can compare them one character at a time:

String x = "test"

String y = "test"

for(int i = 0; i < x.length && i < y.length; i++)

{

if(x[i] != y[i])

return false;

}

return true;

Write a C plus plus program for enumeration and function overloading?

All operators can be overloaded with the exception of the sizeof, typeid, member-of (.), pointer to member (.*), ternary conditional (?:) and scope resolution (::) operators.

Operators may be unary (those that accept one operand) or binary (those that accept two operands). The ternary conditional operator is the only operator that accepts three operands but it cannot be overloaded.

Before overloading an operator, you must first consider the types of its operand(s) and also the type of its return value. All operators must return something, whether it is the logical NOT of an object (a unary operation) or the sum of two objects (a binary operation). However it's easy to get carried away with overloads in order to cater for every possible combination of types, and this can quickly lead to code duplication, inconsistencies and code that is much harder to maintain.

Ideally, all operators should be implemented as free functions (global functions). In so doing you gain the advantage of implicit conversion between types, thus reducing the number of overloads required for any given operation. The only operator overloads that must be implemented as member functions are the copy and move assignment operators, so let's begin with those.

Let's consider a class that encapsulates a year. We'll assume negative years denote BC and positive years denote AD, thus we'll use a signed integral as our representation. However, there was no year zero (we went from 1BC to 1AD), thus our class has an invariant -- it must not be zero.

class year

{

private:

int64_t m_data; // 64-bit signed integral

public:

year (int64_t y): m_data {y} { if (!y) throw std::range_error ("Error: no year zero!"); }

year (const year& y): m_data {y.m_data} {}

year (year&& y): m_data {std::move (y.m_data)} {}

year& operator= (const year& y) {m_data = y.m_data; }

year& operator= (year&& y) { m_data = std::move (y.m_data); }

~year () {}

};

Our class has one conversion constructor which allows us to implicitly convert from any 64-bit integer to a year. However, since the language has built-in conversions for all integrals we can implicitly construct a year from any integral, including a char, an int, a long, a short and so on. The only integral type we cannot implicitly convert is an unsigned 64-bit integral since this could exceed the bounds of our signed integral by up to an order of two. However, the compiler should warn us about this "narrowing" and helps us keep the class as simple as possible.

Note that the conversion constructor is the only constructor that maintains the invariant (non-zero years). Since the copy and move constructors can only work with pre-existing instances of our year class, those instances would not exist unless they had originally been constructed through conversion.

The copy and move assignment operators also cater for pre-existing instances of our year class, but we can also assign from any signed integral because we provided a conversion constructor to cater for this. This makes it possible to perform the following:

year y {2014};

y = -1;

The first statement initialises a year with the literal integral 2014. That is, the value 2014 is implicitly converted to an int64_t (which is what the conversion constructor expects), and the constructor instantiates a year object with that value. The second statement replaces that value with the literal integral -1 even though we did not provide an assignment operator overload to cater for this. Behind the scenes, the compiler constructs a temporary year object from the literal (just as it did with 2014), and then uses that temporary object to perform the actual assignment. The temporary object falls from scope at the end of the statement.

The stream insertion and extraction operators often cause problems for new programmers in the mistaken belief that all operators related to a class should be members of that class just as the copy and move assignment operators must be. However, this is not the case; all other operator overloads should ideally be non-member functions whenever possible, especially when the return value is of a different type. In this case the return value is a reference to the stream being operated upon. We cannot provide these overloads as members of the stream nor as members of the type, therefore we have no option but to define them as free functions:

std::ostream& operator<< (std::ostream& os, const year& y)

{

return os << y.m_data;

}

The problem with this is that year::m_data is private. We could provide a public accessor (in many cases this would be the preferred option), but we must also never expose an interface without good reason. If this were the only function that actually required that accessor then it would not make sense to provide one. A public accessor is intended to be used by anyone and everyone. In this case we could simply return the member by value (and thus maintain encapsulation of the invariant), but in a more complex object we may not wish to expose the entire representation in this way because returning by value can be expensive in terms of both performance and memory. Returning by constant reference is another option but, again, this could expose far more than we wish to expose, which ultimately undermines the encapsulation. The best solution is simply to declare those functions that require private access as friends of the class:

class year

{

// ...

friend std::ostream& operator<< (std::ostream&, const year&);

};

Note that a friend is not a member of the class that declares it a friend, nor does it undermine encapsulation (if anything, it enforces it). The best way to think of it is to examine the three logically distinct things that every ordinary member function declaration specifies:

1. The function has private access to the class representation.

2. The function is in the scope of the class.

3. The function must be invoked upon an instance of the class (has a 'this' pointer).

A static member function declares the first two while a friend only declares the first. It therefore follows that if you believe a friend undermines encapsulation, then you must also believe every member function also undermines encapsulation -- and to a much greater degree. But you are the author of your own class' encapsulation rules; it's entirely up to you how you implement them, whether those implementations are within your own class member functions, your own static member functions or your own friends of the class.

Although friends are not physically members of your class, it would not be entirely wrong to think of them just as if they were. A friend declaration is itself a declaration so there's absolutely nothing to prevent you from defining it inline:

class year

{

// ...

friend std::ostream& operator<< (std::ostream& os, const year& y)

{

return os << y.m_data;

}

};

However, to keep your interface declaration "clean", it is best to place the implementation details outside the declaration, preferably alongside the other class member implementations.

Compound operators such as the increment-assign operator (+=) are often implemented as member functions, however there's no practical reason to do so, especially if you want to take advantage of implicit conversion. Use free functions wherever possible:

year& operator+= (year& lhs, const year& rhs)

{

lhs.m_data += rhs.m_data;

if (!lhs.m_data) throw std::range_error ("Error: no year zero!");

return lhs;

}

The above function must be declared a friend since it requires private access to the representation. However, note that you now have two places where you must check the invariant. Rather than duplicating the code, it would make sense to place that code in a private member function:

class year

{

// ...

private:

void check_invariants { if (!m_data) throw std::range_error ("Error: no year zero!"); }

};

Now the conversion constructor and increment assign operator can be simplified by calling this common method:

year::year (int64_t y): m_data {y} { check_invariants(); }

year& operator+= (year& lhs, const year& rhs)

{

lhs.m_data += rhs.m_data;

check_invariants();

return lhs;

}

With that done, all other increment operators can now be expressed in terms of this one overload without requiring friendship themselves:

// addition

year& operator+ (const year& lhs, const year& rhs)

{

return year {lhs} += rhs;

}

// prefix increment

year& operator++ (year& lhs)

{

return lhs += 1;

}

// postfix increment

year operator++ (year& lhs, const int)

{

year temp {lhs};

lhs += 1;

return temp;

}

All other operators can be implemented by the same means.

Remember, with the exception of the copy and move assignment operators, all other operator overloads should be implemented as free functions, with friend access only where required. Operators that are variations of each other (such as the increment operators), should be implemented in terms of one of those operators.

In some cases it can be helpful to provide a named member function in addition to or in place of an operator overload. For instance, the std::string& std::string::append (const std::string&) member function is synonymous with the std::string& operator+= (std:string&, const std::string&) operator overload. The first is implemented as a named member function, the second as a free function, where the free function simply invokes the member function. In cases where an operation might not be regarded as intuitive, a named member function is usually the best choice because the name can better express the notion of the operator than an operator alone can.

What is the program language c?

C is a pop language.

C is a case sensetive language.

C is motherof all language.

C is block structure language.

C is a high level language.

C is advace of B language.

C developed by D.richties in 1972 at AT & T Bell lab in USA.

Sachin Bhardwaj

986854722

skbmca@gmail.com

Which is 100 percent object oriented language?

There are relatively few 100% object-oriented programming languages, with C#, Ruby and SmallTalk being notable exceptions. Languages such as Java are not 100% object-oriented purely because they still maintain the concept of primitive data types, such as int and char, which are simply not capable of being treated as true objects.

Can you use friend functions to overload operators?

Yes you can. Although you will often hear it said that friend functions undermine encapsulation, this is errant nonsense. Here's a typical example:

#include <iostream>

using namespace std;

class Date

{

private:

int mo, da, yr;

public:

Date( int m, int d, int y ): mo(m), da(d), yr(y) {}

friend ostream& operator<<(ostream& os, const Date& dt);

};

ostream& operator<<(ostream& os, const Date& dt)

{

os << dt.mo << '/' << dt.da << '/' << dt.yr;

return os;

}

int main()

{

Date dt( 5, 6, 92 );

cout << dt;

return( 0 );

}

While it is possible to eliminate the friend function declaration simply by providing public accessors to Date::mo, Date::da and Date::yr, there is no advantage in doing so. You can still provide those accessors, of course, but since you'd need to return those members by value in order to maintain encapsulation, the operator overload would be less efficient as a result. In this case the difference is minimal but, with more complex members, the inefficiency can quickly add up.

Remember that friend functions merely extend the class interface. While it is true that you should not grant friend access to code that you have no control over (and thus undermine any concept of encapsulation), operator overloads such as the insertion operator overload shown above is under your complete control. Ultimately, if it were possible to declare the function as an actual member of the class then you would rightly do so. But that's precisely what you do when you declare friendship. And in this case, that friendship is perfectly legitimate because the alternative, non-friend function, would be less efficient.

What do you mean by operator precedence in c plus plus?

Operator overloading is a mechanism where a C++ developer can assign a special meaning to an operator (such as + or -, for example). This is useful, because it allows developers to create classes that can interact with other classes or primitives naturally, using the same syntax as you'd expect when working with primitives. For example, using operator overloading allows cin and cout to work "magically":

cout << "Hello World" << endl;

Even though it appears that these are just "shift operations", they take on the special meaning of outputting (for cout) and inputting (for cin) without resorting to a more cumbersome:

cout.print("Hello World\n");

This short example doesn't illustrate the savings that this syntax allows; a string of 20 variables would very nicely outline how the shift operators streamline cout.

Unfortunately, this usage is considered controversial, because it allows developers to use odd syntax. Consider the following:

Vehicle car = new Vehicle();

Velocity speed = new Velocity(15);

car += speed;

This is legal syntax with operator overloading. While it might make sense to some developers, others less familiar with a library might need to dig down into the code to make sure that the effect is what the developer intended. This can slow down development and debugging. It is this controversial usage that has prompted future languages, such as Java, to specifically exclude such functionality in an attempt to keep code as legible as possible.

How do you write a class in c plus plus?

Classes are not created, they are designed. A class is merely the definition of a type. The objects you instantiate from those classes are what are actually created, via the class constructors.

What is hierarchical inheritence in c plus plus?

Inheritance is used to define a subclass of a common ancestor. In other words, if you have a class that performs a set of functions, then a class that uses inheritance would have all the functions of the parent class plus additional or modified functions unique to that specific subclass. This allows developers to group common functionality into one class, then provide overrides and additional functionality to child classes. This facilitates code reuse, reduction of code duplication, and polymorphic functions that can operate on several different types of objects using the same base code.

Write a program in'C' language for the implementation of a Stack?

c program for implement a stack using two queue First push the given elements in stack1... then pop those elements and push them in 2nd stack... now pop the elements from this stack... thus implemented queue

Call by reference in c?

If you are calling by reference it means that compilator will not create a local copy of the variable which you are referencing to. It will get access to the memory where the variable saved. When you are doing any operations with a referenced variable you can change the value of the variable.

It is a technique whereby the called function receives values from its calling function, stores these values in its local arguments and returns a result. The called function does not have access to any local variables in the calling function. Anything passed into the function call is unchanged in the caller's scope when the function returns.

No, C uses call-by-value. Of course you may use pointers as parameters.

How to use graphics in c plus plus?

At the beginning in the header file:

#include <graphics.h>

What is a logical operator in c plus plus?

The boolean and operator in C and C++ is &&

a < 3 && b > 4 // relational

The bitwise and operator in C and C++ is &

maskresult = maskinput & maskvalue // bitwise

What is the best C plus plus compiler?

If you mean which is the most standards-compliant then Clang would have to come out on top, closely followed by GCC. MSVC++ is fine if all you do is program in Windows, but its lack of compliance means it is not really C++ -- it's a Microsoft-specific implementation of C++.

How are an objects instance variables initialized of a class has only a default constructor?

You have to explicitly initialise all instance variables, otherwise their values will be initialised to whatever happens to be in memory at the time they are instantiated.

Consider the following class which has no explicit initialisation:

#include <iostream>

class object

{

public:

object(){}

public:

const int getData( void ) const { return( m_data ); }

private:

int m_data;

};

int main()

{

object O;

printf( "O.m_data = %d\n", O.getData() );

return( 0 );

}

Example output:

O.m_data = -858993460

This is not particularly useful; we must ensure m_data is initialised before we access its value.

One way to initialise object::m_data is from within the body of the constructor:

object(){ m_data = 0; } // inefficient initialisation

However this is quite inefficient because object::m_data will have already be instantiated by the time we got to the constructor body. This is akin to the following C-style initialisation:

int x; // instantiate x

x = 0; // initialise x

When what we really want to do is:

int x = 0;

Or use the more formal construction semantics:

int x(0);

Both achieve the same thing. They both initialise the variable x at the point of instantiation, not after instantiation. Fortunately, C++ allows us to initialise all instance variables at the point of instantiation, via the constructor's initialisation section:

object():m_data(0){} // efficient initialisation

While initialising a single primitive data type in the constructor body isn't going to cause major problems in terms of efficiency, with more complex data types the inefficiencies can very quickly add up. Thus it is important to use the initialisation section as much as possible and to only use the body of the constructor when there is no option.

The initialisation section is particularly important when dealing with derived classes. Consider the following:

#include <iostream>

class base

{

public:

base():m_int(0){}

base(const base& object):m_int(object.m_int){}

public:

const int getInt( void ) const { return( m_int ); }

void setInt( const int data ) { m_int = data; }

private:

int m_int;

};

class derived : public base

{

public:

derived():m_float(0.0){}

derived(const derived& object):m_float(object.m_float){}

public:

const float getFloat( void ) const { return( m_float ); }

void setFloat( const float data ) { m_float = data; }

private:

float m_float;

};

int main()

{

derived d;

d.setInt( 1 );

d.setFloat( 2.0 );

printf( "d.getInt() = %d, d.getFloat() = %f\n", d.getInt(), d.getFloat() );

derived c(d); // call copy constructor.

printf( "c.getInt() = %d, c.getFloat() = %f\n", c.getInt(), c.getFloat() );

return( 0 );

}

Example output:

d.getInt() = 1, d.getFloat() = 2.000000

c.getInt() = 0, c.getFloat() = 2.000000

Note that c should be an exact copy of d, but there's clearly a difference in the integer variables inherited from the base class. This is because the derived class copy constructor called the base class default constructor, not the base class copy constructor as you might have expected. To resolve this we must explicitly call the base class copy constructor and the only way to do so is via the initialisation section of the derived class:

derived(const derived& object):base(object),m_float(object.m_float){}

Note that the derived class' copy constructor now includes a call to base(object) in the initialisation section. This ensures the base class copy constructor is called. Although object is actually an instance of derived, because it derived from base it is also a kind of base, thus the call is legitimate. Now if we run the code we'll get the expected result:

d.getInt() = 1, d.getFloat() = 2.000000

c.getInt() = 1, c.getFloat() = 2.000000

As your classes become more and more complex you will inevitably find yourself creating overloaded constructors to provide a wide variety of initialisation methods. But keep in mind that it costs absolutely nothing to use the initialisation sections even if several constructors end up using the exact same initialisations. And while it is tempting to move all of the common initialisation code into a private method of the class and have each constructor call that method (known as a construction helper function), this simply adds yet more inefficiency by introducing yet another unnecessary function call. Helper functions such as these are undoubtedly useful during the initial development of a class but as soon as the class is finalised, get rid of the helper function and move all that functionality into the initialisation sections where they belong. In the case of derived classes, base class constructors will be called whether you like it or not, so it makes sense to call the most appropriate base class constructor from within the initialisation section of each of your derived class constructors. Remember that if you do not specify a base class constructor, its default constructor will be called implicitly, which may or may not be the most appropriate constructor in all cases (not least in the case of the copy constructor).

What is reference variable in c plus plus?

A reference is not a variable of any kind. A reference is simply an alias; an alternate name for an object that already exists. It is analogous to a person with the birth name Robert who might also be known as Robbie, Rob, Rab, Bob and so on. They are all aliases for the same person, so every operation we perform on Bob or Robbie is actually performed on Robert.

Once we assign an object to a reference, we cannot subsequently assign another object to that same reference. Thus a reference is always guaranteed to refer to the same object for as long as that reference remains in scope. Moreover, a reference can never be null; it must always refer to something. As such, references must be assigned to an object at the point of declaration, just as you would a constant.

Note that although a reference is not a variable, the object it refers to can be, unless the reference itself is explicitly declared constant. By the same token, a non-constant reference cannot refer to a constant object.

References are typically used whenever we need to pass an object to a function by reference rather than the usual by value semantics. Like so:

void by_value (int x) {}

void by_reference (int& y) {}

In the above examples, x is a copy of the object we pass to the function, so any changes made to x will not affect the object we passed. However, y is a reference thus any changes made to the object referred to by y will be reflected in the object we passed.

A pointer variable is also a type of reference, but it behaves quite differently. Firstly, a pointer variable really is a variable; it is used to store a memory address thus it requires memory of its own. Secondly, unless the pointer is declared constant, we can change the address a pointer refers to by changing its value. Finally, a pointer may be null.

References are generally much easier to work with and more intuitive than pointers. For instance, we do not need to dereference a reference, thus we can use the member-of operator (.) rather than the pointer-to-member operator (->) when working with object references. Moreover, given that a reference can never be null, there is no need to test for null as we would with a pointer. When passing an object by reference, the function can simply use the reference, safe in the knowledge the reference refers to a valid object. If we pass a pointer, we lose that guarantee and must test the pointer before attempting to dereference it. Nevertheless, there can often be cases where passing an object to a function is optional, in which case we use a pointer argument defaulting to null.

There is also one other type of reference known as an r-value reference. An r-value is an operand that appears on the right-hand-side of an operator. Typically, an r-value is a constant since we would normally expect to only modify the left-hand-operand (the l-value). However, since C++11, move semantics require that an r-value be modifiable. For that reason we use r-value references.

We typically use r-value references when declaring move constructors and move assignment operators, like so:

struct S {

S (const S&); // copy constructor

S& operator= (const S&) // copy assignment

S (S&&); // move constructor

S& operator= (S&&) // move assignment

}

Note that S& is a reference while S&& is an r-value reference. The reason we need an r-value reference is that r-values that are moved are always assumed to be objects that will shortly fall from scope (such as when return an object by value). Thus move semantics must leave the r-value in an unspecified but valid state in order to allow the object to be destroyed. To achieve that, the r-value must be modifiable, hence we use an r-value reference.

The classic scenario is when moving a vector. Copying vectors is highly inefficient, but moving them is simply a case of switching ownership of the resource being moved; the array itself. Once the l-value has taken ownership of the resource, the r-value can simply be switched to an empty state. Note that we don't actually clear the vector (the resource no longer belongs to the r-value) we simply change its internal to state to reflect that of an empty vector. The vector can then be allowed to safely fall from scope.

It should be noted that the C++ compiler may well implement references as constant pointers and r-value references as pointer variables, however that is a matter of concern only to compiler designers. When programming in C++, it is vital that we understand that a pointer is a type while a reference is a programming tool.

How do you write a program in c plus plus that implements the n-queens problem with backtracking?

#include<stdio.h>

#include<conio.h>

#include<math.h>

int a[30],count=0;

int place(int pos)

{

int i;

for(i=1;i<pos;i++)

{

if((a[i]==a[pos])((abs(a[i]-a[pos])==abs(i-pos))))

return 0;

}

return 1;

}

void print_sol(int n)

{

int i,j;

count++;

printf("\n\nSolution #%d:\n",count);

for(i=1;i<=n;i++)

{

for(j=1;j<=n;j++)

{

if(a[i]==j)

printf("Q\t");

else

printf("*\t");

}

printf("\n");

}

}

void queen(int n)

{

int k=1;

a[k]=0;

while(k!=0)

{

a[k]=a[k]+1;

while((a[k]<=n)&&!place(k))

a[k]++;

if(a[k]<=n)

{

if(k==n)

print_sol(n);

else

{

k++;

a[k]=0;

}

}

else

k--;

}

}

void main()

{

int i,n;

clrscr();

printf("Enter the number of Queens\n");

scanf("%d",&n);

queen(n);

printf("\nTotal solutions=%d",count);

getch();

}

What are the merits of volatile in c plus plus?

The volatile specifier informs the compiler that an object could be modified by something that is external to the thread of execution; something that is not part of the program. For instance, when reading a hardware clock, you would rightly expect the value of that clock to change from one read to the next. But from the compiler's perspective, the clock remains constant because your code does not alter it between reads and is unaware of any external code that controls its value. Therefore the compiler will (rightly) optimise away what it believes to be redundant read operations which could easily break the semantics of your code.

By declaring an object volatile (even a constant object), you inform the compiler that the object may change between successive read or write operations and that all redundancy optimisations must not be applied to any code that uses that object.

Although often used as a method of synchronisation between concurrent threads within the same thread of execution that share the same object, you must not use it for this purpose. C++ provides very specific mechanisms for this purpose, such as an atomic, a mutex or a condition_variable. The volatile specifier must only be used when writing low-level code that deals directly with hardware, such as when writing device driver and embedded system software.

What is the difference between actual and formal argument in c plus plus?

Formal parameters are the parameters as they are known in the function definition. Actual parameters (also known as arguments) are what are passed by the caller. For example, in the following code, a and b are the formal parameters, and x and y are the actual parameters:

int max(int a, int b) {
if (a > b) return a;
else return b;
}

int m = max(x, y);

What are the advantages and disadvantages of DLL over single linked list?

The main advantage of a doubly-linked list is that you can traverse and search the list both forwards and backwards. Although you can also add to the beginning and end of the list, and retrieve the same, in constant time O(1), this is also possible with a slightly modified singly-linked list simply by maintaining a pointer to the last node as well as the first.

Thus the only real difference is whether you need to traverse bi-directionally or not. If not, a modified singly-linked list would be more efficient. And if you only require fast access to the first node, a standard singly-linked list would be slightly more efficient.

Disadvantages of multiple inheritance?

If a single class inherits from two other classes, each of which has the same function implemented, how can we tell which one to call? This ambiguity often leads to non-deterministic behavior of classes in multiple inheritance languages.