#questions i have before my midterm

485 messages · Page 1 of 1 (latest)

sturdy oriole
#
void print_height(const Large_Obj& LO){ cout << LO.height(): }

if i run this argument does the passed arugment also have to be const?
or is it only that i cant edit the value of the object while its inside the function

forest dawnBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

lost ferry
#

the const enforces that the function cannot modify the object, not that the object must be const in the first place

sturdy oriole
#

alright

#

thnak you

lost ferry
#

since this is for a midterm... you're asking all these questions, but do the answers we provide make sense? or do you simply intend to remember them by heart and regurgitate them for the exam?

sturdy oriole
#

they make sense

#

i mean

#

its not like their asking exactly

#

what im asking

#

i just need the concept

lost ferry
#

not asking that in a provocative way, sorry if that's how it sounded, but I'd rather give more lengthy explanations if need be, so that you'll have an easier time 😛

sturdy oriole
#

i had an idea already for that question since i asked it that way

#

juts needed to confirm

lost ferry
#

alright cool 👍

sturdy oriole
#

also memorizing seems harder

lost ferry
#

it is

#

at least for me too

#

it's okay to have to remember things because you can't yet exactly make sense of why things are the way they are

#

but I like it to make sense in my mental model so that I don't need to remember and instead reason my way back to the answer

sturdy oriole
#
void print() const
{ cout << year << "/" << month << "/" << day << endl; }
};
#

why is this legal

#

what does const do after the bracket

wise peak
#

ensures this class method can be called on a constant instance of that class

sturdy oriole
#

anythin else?

#

so it gives the like go for the compiler to see

wise peak
#

and that it cant modify class member variables unless they are marked as mutable

sturdy oriole
#

if its a const function

#

it lets const objects call it

#

because safe

wise peak
#
class A {
  public:
  void foo() {}
}

const A instance{};
instance.foo(); // wont compile, foo isnt const qualified and instance is const
wise peak
sturdy oriole
#

alr

#

got it

#

they have it in notes

#

wanted to confirm

#

what does "surprise" mean?

#

i get how the code works

wise peak
#

if a class member variable is marked as mutable, it can be modified within const functions:

class A {
  mutable int mut{};
  int non_mut{};
  public:
  void foo() const {
    mut = ...; // will compile, mut is a mutable member
    non_mut = ...; // wont compile, non_mut is treated as const
  }
}

const A instance{};
instance.foo();
sturdy oriole
#

oh wow

wise peak
sturdy oriole
#

the top

#

they said it

wise peak
#

oh

#

just talking about explicit keyword

#

to avoid implicit conversions by accident/surprise

lost ferry
sturdy oriole
#

like float to int

#

is "titanic" to char* implicit converison

lost ferry
wise peak
#

no, its happening within print_word

#

no as in thats not where the image is trying to point out

#

print_word takes a Word instance, yet its passing in a string and implicitly converting it to a Word instance

sturdy oriole
#

yeah

lost ferry
#

Right my bad, reading skills bad boog

wise peak
#

so if u mark the constructors as explicit it wont allow the implicit conversion, must be explicitly specified

sturdy oriole
#

so i put explicit like

#

let me edit

#

before the consturcotr

#

ok nvm i foudn exmaple

#

explicit Word(const char* s)

#

ok next

#

what is object returned by value

wise peak
#

means a copy

sturdy oriole
#

copy?

wise peak
#
class A{};


A foo() {
  A instance{};
  // do some stuff with instance

  return instance;
}
#

returns by value

sturdy oriole
#

oh

#

so it like returns an object

#

that is created after c opy

wise peak
#

return by reference ```cpp
class A{};

A& foo() {
static A instance{};
// do some stuff with instance

return instance;
}

sturdy oriole
#

are there any cases where you wouldnt use mil

#

and use assigment instead

#

except for like creating new memory

#

ig

sturdy oriole
#

member initializtion lists

sturdy oriole
#

another question

#

compilation error right?

#

cause undefined

sturdy oriole
#

3rd question

#

what exactly is virtual

#

what does it accomplish

#

ima go to bed now

#

if anyone can answer these 3 pls do

#

ill respond tmr

sturdy oriole
#

idkwhat it evne does

elder gale
elder gale
#

Example:

#

;compile -Wall -Wextra

#include <iostream>

// since this class has a pure virtual function it's an abstract class and we can't create an instance of it
struct Animal {
    virtual void name() { std::cout << "unknown animal\n"; }  // virtual function with default implementation - we **can** override this in a subclass
    virtual void sound() = 0;  // pure virtual function - we have to override this in every subclass
};

struct Cow : Animal {
    // note that the 'override' keyword is optional but recommended for readability
    void name() override { std::cout << "Cow\n"; }
    void sound() override { std::cout << "Moo\n"; }
};

struct Pig : Animal {
    void name() override { std::cout << "Pig\n"; }
    void sound() override { std::cout << "oink\n"; }
};

struct UndiscoveredBird : Animal {
    void sound() override { std::cout << "jiiiii\n"; }
    // note how here we didn't override the 'name'  function
};

int main() {
    Cow cow{};
    Pig pig{};
    UndiscoveredBird bird{};

    Animal& a_cow = cow;
    Animal& a_pig = pig;
    Animal& a_bird = bird;

    a_cow.name(), a_cow.sound();
    a_pig.name(), a_pig.sound();
    a_bird.name(), a_bird.sound();
}
solid gobletBOT
#
Program Output
Cow
Moo
Pig
oink
unknown animal
jiiiii
thick umbra
# sturdy oriole what does it accomplish

Virtual functions implement runtime polymorphism

In object-oriented programming such as is often used in C++ and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method that is dispatched dynamically. Virtual functions are an important part of (runtime) polymorphism in object-oriented programming (OOP). They allow for the execution of target fun...

In programming language theory and type theory, polymorphism is the use of a single symbol to represent multiple different types.
In object-oriented programming, polymorphism is the provision of a single interface to entities of different types. The concept is borrowed from a principle in biology where an organism or species can have many diffe...

#

The function (one of many with the same name) is selected at run time, based on the type of the object.

lost ferry
lost ferry
lost ferry
sturdy oriole
#

Which one does it use

lost ferry
#
B b;
b.f(); // calls B::f() on b
D d;
d.f(); // calss D::f() on d, which itself ends up calling B::f() on d
sturdy oriole
#
#include <iostream>
using namespace std;
class A {
  public:
  A(int n): x(n) {}
  void print() {
    cout << x << endl;
  }
private:
int x;
};
void fun(const A obj) {
  obj.print();
  }
int main() {
  A objA {10};
  fun(objA);
  return 0;
}
#

what is the error here

#

is it the A objA {10};

peak seal
#

;compile cpp #include <iostream> using namespace std; class A { public: A(int n): x(n) {} void print()const{ cout << x << endl; } private: int x; }; void fun(const A obj) { obj.print(); } int main() { A objA {10}; fun(objA); return 0; }

solid gobletBOT
#
Program Output
10
solid gobletBOT
#
Compiler Output
<source>: In function 'void fun(A)':
<source>:13:12: error: passing 'const A' as 'this' argument discards qualifiers [-fpermissive]
   13 |   obj.print();
      |   ~~~~~~~~~^~
<source>:6:8: note:   in call to 'void A::print()'
    6 |   void print() {
      |        ^~~~~
Build failed
peak seal
#

A::print method needs to be const-qualified

#

or change the function signature of void fun(const A obj) to void fun(A obj)

sturdy oriole
#

does compiler detect this at start

#

also for this

#
#include <iostream>
using namespace std;
class D {
private:
int d;
public:
D(int n) : d(n) {}
D& decrement() {
d--;
return (*this);
}
D fun1(D& other) {
return (d > other.d ? decrement() : other.decrement());
}
D& fun2(D& other) {
return (d < other.d ? decrement() : other.decrement());
}
void print() const {
cout << d << endl;
}
};
int main() {
D n1(3), n2(1), n3(5);
n1.fun1(n2).fun2(n3);
n1.print();
return 0;
}

what does n1.fun1(n2).fun2(n3); do

sturdy oriole
#

i figured it out

forest dawnBOT
#

@sturdy oriole Has your question been resolved? If so, type !solved :)

sturdy oriole
#

how do i know what this does

#

g++ -std=c++11 -fno-elide-constructors SQ-order-ctor-dtor.cpp -o SQ-order-ctor-dtor

#

man

#

what the hell is makefile why are they testing it

lost ferry
#

did you read or otherwise follow your course at all during the semester hmmGe

#

also when is your midterm exam

sturdy oriole
sturdy oriole
#

but it was really annoying so i just compiled the main

#
#include <iostream>
using namespace std;

class A {
    int a;
public:
    A(int a = 0) : a(a) { cout << "AC1" << endl; }
    A(const A& a) : a(a.a) { cout << "AC2" << endl; }
    ~A() { cout << "AD" << endl; }
};

class B {
    int b;
public:
    B(int b) : b(b) { cout << "BC1" << endl; }
    B(const B& b) : b(b.b) { cout << "BC2" << endl; }
    ~B() { cout << "BD" << endl; }
};

class C {
    A a;
    B b;
    int c;
public:
    C() : c(10), a(A()){ cout << "CC" << endl; }
    ~C() { cout << "CD" << endl; }
};

class D {
    A a{10};
    B b{20};
    C c;
public:
    D() { cout << "DC" << endl; }
    ~D() { cout << "DD" << endl; }
};

int main() {
    cout << "Beginning of main" << endl;
    D obj;
    D obj2;
    cout << "End of main" << endl;
}

#

this function

#
AC1
BC1
AC1
AC2
AD
BC1
BC2
BD
CC
DC
End of main
DD
CD
BD
AD
BD
AD

#

they gave this as output

#

when is bc2 hpapening

#

i do not understand

lost ferry
#

the output seems to be only half as long as it should be

#

so I'll assume the code that produced this had only D obj; and not D obj2;

lost ferry
lost ferry
#

D obj2; declares an object of type D named obj2 and calls its default constructor
D obj2(); declares a function named obj2 which takes no parameter and returns an object of type D

#

the former would produce what D obj; already does (and which you posted), the latter simply states "this is a function that exists" and does nothing else

sturdy oriole
#

but where is bc2

#

being copied

#

i dont see it

#

wait

#

look at function agian

#

there was extra line there

#

mb

lost ferry
#

okay, now I think this shouldn't compile

#

B has no default constructor and is not initialized with parameters that match one of its constructors

sturdy oriole
#

B(const B& b = 0) : b(b.b) { cout << "BC2" << endl; }

#

isnt this kinda default

lost ferry
#

ah yes, should have looked at the original

#

so yes that's exactly where it comes from

sturdy oriole
#

why is bc1 there then

#

rn my order of what i see is
creates d

#

AC1
BC1

#

creates c
AC1 BC2
then AC2 AD

#

right???

#

theres n o bc1

#

im tirpping

lost ferry
#
  • C is default constructed
    • first, c is initialized
    • then, A is default constructed (A1) and the result is fed into the copy constructor of A (A2)
    • only then, B is being default constructed, for which the only eligible constructor is B(const B& b = 0), so it gets called with a default argument constructed from 0
      • the argument type is still const B& though so somehow 0 needs to be turned into a B
        • THIS is what calls the B1 constructor of B which takes an int
      • the resulting object is the actual argument to the copy constructor of B, which outputs B2
#

well the bullet points are all fucked up but you get the idea

#

note that this only happens because the file is compiled with -fno-elide-constructors

sturdy oriole
#

i have no idea what that does

lost ferry
#

otherwise, any sane compiler probably merges the constructor calls without generating temporary copies, and is obligated to do so in C++17 and later

sturdy oriole
#

okok so it runs default on b which then creates a const b from 0

lost ferry
#

(this is compiled in c++11 according to the command line that you posted though, compilers still probably eliminated the extraneous constructor calls)

lost ferry
sturdy oriole
#

yeah\

lost ferry
#

it runs the copy constructor with a default argument

sturdy oriole
#

i mean the copy thing

#

yeah

#

so the copy runs the b(0) constructor

#

so its bc1 bc2 then deletes the b(0) constructor

lost ferry
#

I might seem nitpicky but the distinction will probably be important in your midterm

sturdy oriole
#

yeah

#

i hate exams so much for cs

#

literlaly makes no sense

#

0 application in real life

#

will never help me

lost ferry
sturdy oriole
#

ye

#

also last one

#

for the destructor order

#

why does it call class "C" destructor first

lost ferry
sturdy oriole
#

i juust hate the format

#

i wish they would just give like

#

a big project

lost ferry
lost ferry
#

and then the same thing happens

sturdy oriole
#

ah

#

alright good to know

lost ferry
#

in each of them, destructor body first, member destructors in reverse order then

lost ferry
sturdy oriole
#

ok

#

they have this weird thing too where virtual functions are thought

#

but not adts

#

because they havent reached it

#

but they will still be in the exam

lost ferry
#

lol

#

classic school BS

sturdy oriole
#

the adts wont

#

but virtuals will

#

but both of them are tied to each other

#

all i know is that you can override virtuals

#

thats all

lost ferry
#

Note that references are being used in main, and that's important

#

You can also read the chapters of learncpp that I linked above

sturdy oriole
#

also is melvor

#

that runescape idle game

#

i saw it once i think when i was lookingm for idle gmaes

#

i will be reseraching lambda expressions now sincei dont understand them

lost ferry
sturdy oriole
#

what would have been differnet if they were allowed to use copy elison

lost ferry
#

Not sure about B (I think it would have remained there; worth checking) but you would see no copy constructor call for A

#

Most compilers did it before C++17, it's guaranteed to happen from C++17 onwards

#

That is, class instances that are move/copy-constructed from temporaries are instead constructed directly using the argument that said temporaries are constructed from

#

(roughly)

sturdy oriole
lost ferry
#

Yes

sturdy oriole
#

how would that work

#

it doenst run the mil

#

i mean it runs the mil

lost ferry
#

It does, but the compiler detects that a is copy constructed from a temporary A instance and instead constructs a just like it would the temporary

#

The temporary isn't involved anymore

sturdy oriole
#

ic

#

so no ac1?

#

wait no

#

no ac2

#

cause the ac2 part is the useless copying part

#

oh my god this hurts my head

sturdy oriole
#
#include <iostream>
using namespace std;
int main()
{
int a = 1, b = 1, c = 1;
auto f1 = [a, &b, &c] () mutable {
cout << a << " " << b << " " << c << '\n';
auto f2 = [a, b, &c] () mutable {
cout << a << " " << b << " " << c << '\n';
a = b = c = 4;
};
a = b = c = 3;
f2();
};
a = b = c = 2;
f1();
cout << a << " " << b << " " << c << '\n';
}
#

;format

solid gobletBOT
#
Critical error:

Unable to find code to format!

Please reply to a message when executing this command or supply the code yourself in a code block or message attachment.

solid gobletBOT
# sturdy oriole ;format
#include <iostream>
using namespace std;
int main()
{
    int a = 1, b = 1, c = 1;
    auto f1 = [a, &b, &c]() mutable {
	cout << a << " " << b << " " << c << '\n';
	auto f2 = [a, b, &c]() mutable {
	    cout << a << " " << b << " " << c << '\n';
	    a = b = c = 4;
	};
	a = b = c = 3;
	f2();
    };
    a = b = c = 2;
    f1();
    cout << a << " " << b << " " << c << '\n';
}

Powered by godbolt.org

sturdy oriole
#

if its excecuted when f2(); is called

#

why does it not capture 3 3 3

#

am i stupid

#

like a=b=c=3;

#

so all values are 3

#

then it should capture all 3 right?

#

or because c is reference does it get the global value

#

from main

solid gobletBOT
#
Program Output
1 2 2
1 2 3
2 3 4
sturdy oriole
#

thought it would be
1 2 2
3 3 3
2 3 4

wise peak
#

ur modifying them after they have been captured

sturdy oriole
#

so capture happens before the f2(); call?

#

but when it is written?

wise peak
#

the capture happens the moment u write it

#

unless its a capture by reference, it will capture by value aka copy the value

#

thats why the first print says 1 2 2, 1 was copied when it was 1, the rest were references and the references memory was updated

sturdy oriole
#

okay

#

good to know

#

so it happens when write not when exceutre

wise peak
#

capture happens when written yes

#

u can easily understand why:

#

have u learnt about operator overloading

sturdy oriole
#

yeah

#

kidna

wise peak
#

have u learnt about functors

sturdy oriole
#

what

wise peak
#

its where a class overloads the () operator

sturdy oriole
#

no

#

okay got it

#

got 1 2 3

wise peak
#
#include <iostream>
class A {
  public:
  int operator()(/*parameters*/) {
    return 69;
  }
};

int main() {
  A instance{};
  std::cout << instance();
}
solid gobletBOT
#
Compiler Output
<source>: In function 'int main()':
<source>:10:8: error: 'cout' is not a member of 'std'
   10 |   std::cout << instance();
      |        ^~~~
<source>:1:1: note: 'std::cout' is defined in header '<iostream>'; this is probably fixable by adding '#include <iostream>'
  +++ |+#include <iostream>
    1 | class A {
Build failed
sturdy oriole
#

gg

wise peak
#

forgot include

solid gobletBOT
#
Program Output
69
wise peak
#

that is basically a functor

#

and when u define the lambda, same thing happens

sturdy oriole
#

oohg

#

then they use auto in questions

#

amazing

#

im going to shank my professor

#

what does mutable do to lambda?

#

i assume it makes it so we can change the parameters?

wise peak
#
int a{};
auto lambda = [a](){ return a; };

// the lines above are equivalent to the auto generated code below:
class lambda
{
  int a;
  public: 
  lambda(int& _a) : a{_a} {}
  int operator()() const {
    return a;
  }
};

lambda lambda_instance {a};

lambda_instance(); // whenever u want to call the lambda
#

and if u remember i told u that constant class methods can not modify the member variables

#

mutable on a lambda is the same as making the member variables of the generated lambda structure mutable ||it just removes the const qualification though!||

sturdy oriole
#

yeah

#

but if i dont put mutable

#

can i change

#

or is it const defaulkt

wise peak
#

no because the functor is const and thats what gets called when u do lambda()

#

that class is what the compiler generates

#

a lambda is a functor

#

and if u were to capture a by reference, the member variable would change from int a; to int& a;

sturdy oriole
#

ok

#

so if i were to like

#
#include <iostream>
using namespace std;
int main()
{
    int a = 1, b = 1, c = 1;
    auto f1 = [a, b, c](){
    cout << a << " " << b << " " << c << '\n';
    auto f2 = [a, b, c]() {
        cout << a << " " << b << " " << c << '\n';
        a = b = c = 4;
    };
    a = b = c = 3;
    f2();
    };
    a = b = c = 2;
    f1();
    cout << a << " " << b << " " << c << '\n';
}
solid gobletBOT
#
Compiler Output
<source>: In lambda function:
<source>:10:15: error: assignment of read-only variable 'b'
   10 |         a = b = c = 4;
      |             ~~^~~~~~~
<source>: In lambda function:
<source>:12:7: error: assignment of read-only variable 'a'
   12 |     a = b = c = 3;
      |     ~~^~~~~~~~~~~
Build failed
sturdy oriole
#

huh

#

okay

#

ohh cause it mutates the type

wise peak
solid gobletBOT
#
Compiler Output
<source>: In lambda function:
<source>:10:19: error: assignment of read-only variable 'c'
   10 |         a = b = c = 4;
      |                 ~~^~~
<source>: In lambda function:
<source>:12:15: error: assignment of read-only variable 'c'
   12 |     a = b = c = 3;
      |             ~~^~~
Build failed
sturdy oriole
#

ok

#

im looking at it

#

what am i supposed to look at

#

oh

#

nvm

#

its all just classes

#

wow

wise peak
#

that should help u visualize captures by value, by reference and the mutable keyword on lambdas etc

sturdy oriole
#

const by default withoit mutable

wise peak
#

the class instance gets created the moment u define the lambda, but the operator() is only called when u want to, this is why it holds the original values copied by value

sturdy oriole
#

i have achieved sentience

#

i will sleep better before my exam

#

that website is really cool

wise peak
#

it is

sturdy oriole
#

what is copy elison?

#

exactly

wise peak
#

i was gone

sturdy oriole
#

he is ogne

wise peak
#

form of optimization^

#

i think it started from c++11

sturdy oriole
#

oh

wise peak
#

cant remember exactly

sturdy oriole
#

i saw a question where it had like 3 classes

#

the base

#

the derived

#

and derived from derived

#

and the 2nd layer had a virtual function but the first one didnt(both had same name)

#

and how does that work

#

i cannot find the question

wise peak
#

unnecessary copy avoiding aka return value optimization

sturdy oriole
wise peak
#

idk provide the code

sturdy oriole
#

im trying to find it

#

should i just rewrite

wise peak
#

ill go take a nap while ur at it

sturdy oriole
#

alright

#
#include <iostream>    
using namespace std;

class Base 
{
  public: 
    Base() { cout << "Base's constructor\n"; }
    ~Base() { cout << "Base's destructor\n"; }
};

class Derived : public Base 
{
  public: 
    virtual Derived() { cout << "Derived's constructor\n"; }
    ~Derived() { cout << "Derived's destructor\n"; }
};

class Derived2 : public Derived
  {
    public: 
    Derived() { cout << "Derived's constructor\n"; }
    ~Derived() { cout << "Derived's destructor\n"; }
}

int main() 
{ 
    Base* p = new Derived; 
    delete p; 
}

#

something like tihs

#

idk i may have been tripping

#

cause my cmpiler doesnt like it

lost ferry
#

virtual constructors don't exist

#

and classes cannot have constructors that are not their own

#

(Derived2 can only have Derived2 constructors)

sturdy oriole
#

wait

#

its destructors

lost ferry
#

the destructor needs to be virtual in any derived class that will be managed through its base class

#

otherwise you expose yourself to nasty stuff

sturdy oriole
lost ferry
#

no, the base class destructor is fine

#

the derived classes' destructors aren't

#

(and Derived2 still cannot have a destructor for Derived, it makes no sense)

sturdy oriole
#

oh yeah

#

i just kinda copoy pasted it

#

lemme

#

uh

#
#include <iostream>    
using namespace std;

class Base 
{
  public: 
    Base() { cout << "Base's constructor\n"; }
    ~Base() { cout << "Base's destructor\n"; }
};

class Derived : public Base 
{
  public: 
    Derived() { cout << "Derived's constructor\n"; }
    virtual ~Derived() { cout << "Derived's destructor\n"; }
};

class Derived2 : public Derived
  {
    public: 
    Derived2() { cout << "Derived2's constructor\n"; }
    ~Derived2() { cout << "Derived2's destructor\n"; }
};

int main() 
{ 
    Base* p = new Derived; 
    delete p; 
}

#

so this legal

#

so the derived 2 can overide the derived 1 thing

lost ferry
#

there is not overriding taking place here

#

overriding is a thing for regular member functions

sturdy oriole
#

what are the yaccomplishing him

#

here*

lost ferry
#

what do you think is happening?

sturdy oriole
#

i dont know

#

it does nothing?

#

the virtual thing

lost ferry
#

there are constructor and destructor calls involved and they print to the output so surely something observable must be happening

sturdy oriole
#

oh

#

thats what yo umeant

#

uh

lost ferry
#

maybe try to play around with this code on your computer or on compiler explorer

maiden wave
#

Try copying the code and running it, then remove the virtual keyword and see what's different

lost ferry
#

see what happens when you remove virtual from Derived's destructor declaration

#

lol you sniped me PES_Sniper

sturdy oriole
#

Base's constructor
Derived's constructor
Derived's destructor
Base's destructor

lost ferry
#

cool

#

now can you try to guess what would happen without virtual

#

if you can't, now is a good time to try it out

sturdy oriole
#

Base's constructor
Derived's constructor
Base's destructor

lost ferry
#

seems like you got it then

#

how do you explain what happens here

maiden wave
#

Also, try changing the line to Derived* p = new Derived then try both with virtual and without again

#

Look at what's different

sturdy oriole
#

why doesnt it do derived destructor

#

oh wait

#

the pointer is for base

#

ok

#

so virtual makes it so the pointer deletes the correct class?

lost ferry
#

yes, exactly

#

and as you very correctly noted, it's a combined effect of both having virtual functions and using them through a pointer or a reference

sturdy oriole
#

okay im a test the double virtual function thing

#
#include <iostream>    
using namespace std;

class Base
{
public:
    Base() { cout << "Base's constructor\n"; }
    ~Base() { cout << "Base's destructor\n"; }
    virtual void f() { cout << "bals"<<endl; }
};

class Derived : public Base
{
public:
    Derived() { cout << "Derived's constructor\n"; }
    ~Derived() { cout << "Derived's destructor\n"; }
     void f() override{ cout << "bals1"<<endl; }
};

class Derived2 : public Derived
{
public:
    Derived2() { cout << "Derived2's constructor\n"; }
    ~Derived2() { cout << "Derived2's destructor\n"; }
    void f() override { cout << "bals3"<<endl; }
};

int main()
{
    Base* p = new Derived;
    p->f();
    delete p;
}
#

this broken?

#

i guess i cant have 2nd layer virtual void

lost ferry
#

why couldn't you

sturdy oriole
solid gobletBOT
#
Program Output
Base's constructor
Derived's constructor
Base's destructor
sturdy oriole
#

what

#

my compiler wont compile it

#

nvm it compiles but my compiler tweaks out

solid gobletBOT
#
Program Output
Base's constructor
Derived's constructor
balsBase's destructor
sturdy oriole
#

what

solid gobletBOT
#
Program Output
Base's constructor
Derived's constructor
bals1
Base's destructor
solid gobletBOT
#
Program Output
Base's constructor
Derived's constructor
Derived2's constructor
bals3
Base's destructor
solid gobletBOT
#
Program Output
Base's constructor
Derived's constructor
bals1
Base's destructor
sturdy oriole
#
class A {
int* p;
public:
A() { p = new int; }
~A() { delete p; }
};
int main() {
A obj1, obj2;
obj1 = obj2;
}
#

why is tus double free

solid gobletBOT
sturdy oriole
#

what does obj1=obj2; do exactly

#

does it not delet eobj1

#

why would that cause a double free

wise peak
sturdy oriole
#

ok

wise peak
#

resulting in 2 frees of the same pointer and 0 frees of the first pointer

sturdy oriole
#

and obj1 deleted?

#

same pointer?

#

how does it delete twice

wise peak
#
obj1 = obj2 ===== obj1.p = obj2.p
sturdy oriole
#

oh

#

ok

wise peak
#

obj1.p was lost, never deleted

#

obj2.p was copied, deleted twice

sturdy oriole
#

ok

#

ok obj 1 was lost

#

how was obj2 deleted twice

wise peak
#
int* obj1_p = new int();
int* obj2_p = new int();

obj1_[ = obj2_p; // obj1_p and obj2_p hold the same value now, this is a copy of the pointer

delete obj1_p; // these 2 have the same value:
delete obj2_p;
sturdy oriole
#

ohhh

#

i tohught i t was copy9ing the whole class

sturdy oriole
#

is it like default

#

for classes to copy all member values?

wise peak
sturdy oriole
#

i thought it was creating a new class

wise peak
#

its a copy

#

these are called special member functions:

#
  • constructor
  • destructor
  • copy assignment (copy operator / copy assignment operator)
  • copy constructor
  • move assignment (move operator / move assignment operator)
  • move constructor
#

the compiler follows a set of rules to determine which of these need to be defaulted and implicitly defined by the compiler

#

u can look up c++ special member function compiler rules

#

but in ur example the compiler defined the copy assignment

wise peak
#

im just introducing relevant things to u so u dont just memorize why something happens instead understand why @sturdy oriole

sturdy oriole
#

ok

wise peak
#

ur next lesson is probably gonna be move semantics or something similar

sturdy oriole
#
#include <iostream>
using namespace std;
class A
{
public:
void nonConstMemFunc() { }
void constMemFunc() const { }
const A getConstObj() { return *this; }
const A& getConstRefObj() { return *this; }
};
int main()
{
const A constObj;
constObj.nonConstMemFunc(); /* Error: Yes / No */
constObj.constMemFunc(); /* Error: Yes / No */
A nonConstObj;
A nonConstObj2 = nonConstObj.getConstObj(); /* Error: Yes / No */
A nonConstObj3 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
A& nonConstRefObj1 = nonConstObj.getConstObj(); /* Error: Yes / No */
A& nonConstRefObj2 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
const A constObj2 = nonConstObj.getConstObj(); /* Error: Yes / No */
const A constObj3 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
const A& constRefObj1 = nonConstObj.getConstObj(); /* Error: Yes / No */
const A& constRefObj2 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
A& const mystery = nonConstObj.getConstObj(); /* Error: Yes / No */
return 0;
}

;format

solid gobletBOT
# sturdy oriole ;format
#include <iostream>
using namespace std;
class A {
public:
    void nonConstMemFunc() { }
    void constMemFunc() const { }
    const A getConstObj() { return *this; }
    const A& getConstRefObj() { return *this; }
};
int main()
{
    const A constObj;
    constObj.nonConstMemFunc(); /* Error: Yes / No */
    constObj.constMemFunc(); /* Error: Yes / No */
    A nonConstObj;
    A nonConstObj2 = nonConstObj.getConstObj(); /* Error: Yes / No */
    A nonConstObj3 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
    A& nonConstRefObj1 = nonConstObj.getConstObj(); /* Error: Yes / No */
    A& nonConstRefObj2 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
    const A constObj2 = nonConstObj.getConstObj(); /* Error: Yes / No */
    const A constObj3 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
    const A& constRefObj1 = nonConstObj.getConstObj(); /* Error: Yes / No */
    const A& constRefObj2 = nonConstObj.getConstRefObj(); /* Error: Yes / No */
    A& const mystery = nonConstObj.getConstObj(); /* Error: Yes / No */
    return 0;
}

Powered by godbolt.org

sturdy oriole
#

ok

#

are the rules i state there correct

#

const object or reference cnanot be implicitly converted to non const reference

#

but the other implicit versions here are fine?

silk maple
#

a const A& can bind to any kind of A

#

A& needs a non-const A

#

for a variable of type A, it depends on whether you have a copy constructor or what you're getting from a function call, etc.

#

A& const is fun

sturdy oriole
sturdy oriole
#

I’m dead

#

70 maximum

#

Most likely 55

#

Thanks for all the help fellas

#

Prob would’ve been 30 without the help

forest dawnBOT
#

@sturdy oriole Has your question been resolved? If so, type !solved :)

silk maple
#

a reference const a& binds to whatever it is initialized with

#

you bind references to things

sturdy oriole
#

oh

sturdy oriole
#

!solved