1.11.2018

Why do we need virtual functions in C++? (轉貼)

Why do we need virtual functions in C++?



1989

down voteaccepted
I'm a C++ newbie myself, but here is how I understood not just what virtual functions are, but why they're required:
Let's say you have these two classes:
class Animal
{
    public:
        void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};
In your main function:
Animal *animal = new Animal;
Cat *cat = new Cat;

animal->eat(); // Outputs: "I'm eating generic food."
cat->eat();    // Outputs: "I'm eating a rat."
So far so good, right? Animals eat generic food, cats eat rats, all without virtual.
Let's change it a little now so that eat() is called via an intermediate function (a trivial function just for this example):
// This can go at the top of the main.cpp file
void func(Animal *xyz) { xyz->eat(); }
Now our main function is:
Animal *animal = new Animal;
Cat *cat = new Cat;

func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating generic food."
Uh oh... we passed a Cat into func(), but it won't eat rats. Should you overload func() so it takes a Cat*? If you have to derive more animals from Animal they would all need their own func().
The solution is to make eat() from the Animal class a virtual function:
class Animal
{
    public:
        virtual void eat() { std::cout << "I'm eating generic food."; }
};

class Cat : public Animal
{
    public:
        void eat() { std::cout << "I'm eating a rat."; }
};
Main:
func(animal); // Outputs: "I'm eating generic food."
func(cat);    // Outputs: "I'm eating a rat."
Done.

7.08.2017

大量PNG圖去背轉GIF圖檔

1. 安裝 ImageMagick
(2.a 單轉檔, MJt1.png轉MJt1.gif)
>convert "MJt1.png" -transparent #ffffff "output\MJt1.gif"

2.b *.png去背(白色去背#ffffff)轉gif

>FOR %G IN ("*.png") DO convert "%G" -transparent #ffffffff "output\%G.gif"

==>會生成許多*.png.gif

3.用Windows PowerShell,將*.png.gif轉成*.gif
>Dir | Rename-Item -NewName { $_.name –eplace "png.gif", "gif" }

Note:在cmd下用ren *.png.gif *.gif無効…

11.05.2015

Python 3超新手常犯的錯誤

##注意parameter的值是variable時,不會跟著variable的值來改變

t = 0

def p(a=t):
    print("a=%d"%a)

def main():
    global t
    t = 100
    p()
    print("t=%d"%t)

if __name__ == "__main__":
    main()

##############Output#############
a=0
t=100

10.20.2015

Python3 "from m import *" 超新手常犯的錯誤

#在python 3, 請注意s的值並不會共用
# a.py
from b import *

def main():
    global s
    print(s)
    add()
    print(s)
    s += 6
    print(s)
    add()
    print(s)

if __name__ == "__main__":
    main()

# b.py
s =10

def add():
    global s
    s += 1
    print("s=%d"%s)

###
# Execute a.py
###
10
s=11
10
16
s=12
16

#如果要s的值共用,可以如下修改:
# a.py
import b

def main():
    print(b.s)
    b.add()
    print(b.s)
    b.s += 6
    print(b.s)
    b.add()
    print(b.s)

if __name__ == "__main__":
    main()

# b.py (不變)
s =10

def add():
    global s
    s += 1
    print("s=%d"%s)

###
# Execute a.py
###
10
s=11
11
17
s=18
18

9.25.2015

Can't log in to ubuntu 12.04 (轉貼)

I can't log in to my ubuntu 12.04. Once I login I got returned back to the original screen after a trial to enable X11 Forwarding.
Can you help me with this.
shareimprove this question
   
Are you trying to login remotely? What did you do to try to enable X11 forwarding? –  izx May 19 '12 at 21:40
   
Does this only happen when trying to log in remotely? Or are you having this problem logging in locally as well? –  Eliah Kagan Mar 27 '13 at 1:07
   
Check your .xsession-errors in your home directory, I found an error over there, fixed it, then I can login from desktop. I did try to change the permission and ownership of .Xauthority but it doesn't help in my case. – user288195 Jun 3 '14 at 23:25

9 Answers

I haven't tried to enable X11Forwarding, but I used to have the same problem. You can fix this in a few steps:
  • When you get to the graphical login screen, hit Ctrl+Alt+F2, thus you get to a textual login.
  • Put in your name and password (password is not displayed when you type, neither as stars or bullets).
  • Type sudo apt-get install gdm and hit enter, give your password and wait to get a line ending with a dollar sign again.
  • Type sudo dpkg-reconfigure gdm.
  • Hit Enter at the first screen.
  • Select gdm in the list you get in the second screen with the arrow keys.
  • Hit the Tab button (above the caps lock one). Now you see the word Ok highlighted. Hit Enter.
  • Type sudo reboot and hit enter. You'll get another graphical login screen, but you'll be able to log in!
P.S.:
  1. If you are used to running some programs like ifconfig or others which are administrative ones from a terminal emulator (e.g. gnome-terminal) you'd better add a line like PATH="$PATH:/sbin:/usr/sbin" at the end of the .bashrc file in your home directory. You can do it with echo 'PATH="$PATH:/sbin:/usr/sbin"' >> ~/.bashrc.
  2. If you want to change back to the other graphical login screen from time to time and see if it was bug-fixed and it works again you can run sudo dpkg-reconfigure gdm and select lightdm and reboot (doesn't look like it works if you just run sudo pkill X).
shareimprove this answer

9.07.2015