Switch and Light

I am envisioning a panel with a series of switches, buttons and/or toggles. This panel is connected to a series of devices such as lights windows etc... Each devise would have two states. Usually on/off or open/closed determined by true/false booleans. Am I approaching this problem right? If so, how do I create or expand a class to allow the devices to be directly controlled by the toggles?

P.S. Some of the code is just to test that I can toggle the switches.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;

class toggle//the switch
{
public:
    void set(bool b){x = b;}
    bool call(){return x;}
private:
    bool x;
};
class device//controlled by toggle(switch)
{
public:
    void set(bool b){x=b;}
    bool call(){return x;}
private:
    bool x;
};

int main()
{
    bool b1=false,b2=true,b3=false;
    toggle tlight;
    toggle tlock;
    toggle tsprinkler;
    device light;
    device lock;
    device sprinkler;

    tlight.set(1);
    cout << tlight.call() << " ";
    tlock.set(0);
    cout << tlock.call() << " ";
    tsprinkler.set(1);
    cout << tsprinkler.call() << " ";
    cout << endl;

    return 0;
}

closed account (D80DSL3A)
I would give each device a pointer (or a reference) to a toggle.
1
2
3
4
5
6
7
8
class device//controlled by toggle(switch)
{
public:
    device(toggle t): pt(t){}// constructor
    bool call(){return *pt.x;}
private:
    toggle* pt;// pointer to a toggle
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    toggle tlight;
    device light( &tlight);// associate toggle with device

    tlight.set(1);
    cout << light.call() << " ";// light is on
    
    tlight.set(0);
    cout << light.call() << " ";// light is off
    cout << endl;

    return 0;
}
i am getting a bunch of errors after trying to compile with your corrections. I am not near familiar enough with pointers to be able to fix this. Can you please walk me through the code so I can fix the problem myself?

||=== Switches, Debug ===|
G:\CodeBlocks-Programs\Switches\main.cpp||In constructor 'device::device(toggle)':|
G:\CodeBlocks-Programs\Switches\main.cpp|15|error: cannot convert 'toggle' to 'toggle*' in initialization|
G:\CodeBlocks-Programs\Switches\main.cpp||In member function 'bool device::call()':|
G:\CodeBlocks-Programs\Switches\main.cpp|16|error: request for member 'x' in '((device*)this)->device::pt', which is of non-class type 'toggle*'|
G:\CodeBlocks-Programs\Switches\main.cpp||In function 'int main()':|
G:\CodeBlocks-Programs\Switches\main.cpp|24|error: no matching function for call to 'device::device(toggle*)'|
G:\CodeBlocks-Programs\Switches\main.cpp|15|note: candidates are: device::device(toggle)|
G:\CodeBlocks-Programs\Switches\main.cpp|13|note: device::device(const device&)|
||=== Build finished: 3 errors, 0 warnings (0 minutes, 2 seconds) ===|


Here is my revised code(in case you need it):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;

class toggle//the switch
{
public:
    void set(bool b){x = b;}
    bool call(){return x;}
private:
    bool x;
};
class device//controlled by toggle(switch)
{
public:
    device(toggle t): pt(t){}// constructor
    bool call(){return *pt.x;}
private:
    toggle* pt;// pointer to a toggle
};

int main()
{
    toggle tlight;
    device light( &tlight);// associate toggle with device

    tlight.set(1);
    cout << light.call() << " ";// light is on

    tlight.set(0);
    cout << light.call() << " ";// light is off
    cout << endl;

    return 0;
}

This code should work:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

#include <cstdlib>
#include <iostream>
using namespace std;

class toggle //the switch
{
public:
    void set(bool b){x = b;}
    bool call(){return x;}
protected:
    bool x;
};
class device : public toggle  //inherited from toggle(switch)
{
public:
    device(): toggle(){};  //constructor
    bool call(){return x;}

};

int main()
{
    device tlight;


    tlight.set(1);
    cout << "light is on: "<< tlight.call() << endl; // light is on

    tlight.set(0);
    cout << "light is off: " << tlight.call() << endl; // light is off
    cout << endl;

    system("PAUSE");
    return EXIT_SUCCESS;
}

Last edited on
Thanks a lot guys. It worked. I will have to look over it to see what I can learn. i might have to ask more questions later. I hope you don't mind.
I'm sorry fun2code. You've always been helpful..but I am finding it extremely difficult to understand how to get pointers to work. Especially in classes. This, of course, is my biggest weakness to this point.
Then you're over-complicating them =] Simplify- they're forwarding addresses, and variables are houses.
Thank you for your response, ultinitus. The problem is more syntax than concept.
& = address of
* = value of (or pointer declaration)

1
2
int variable = 9; //I'm a variable!!
int* intpointer = &variable; //I'm a pointer, and I forward to variable's address! 


The only other thing you really need to know is dereferencing, or essentially getting the original object.

saying (*intpointer) is the exact equivalent of saying variable.
closed account (D80DSL3A)
Here is a revised device class. Sorry for the earlier errors. I should know not to post when I have to leave for work! No chance to correct a rushed job.

I tested this and it works:
1
2
3
4
5
6
7
8
class device//controlled by toggle(switch)
{
public:
    device(toggle* pt): p_tog(pt){}// constructor takes a pointer as argument
    bool call(){ return p_tog->call(); }// must call call() since x is private
private:
    toggle* p_tog;// pointer to a toggle
};


I don't see a reason for device to inherit toggle though.
You could use a reference to a toggle instead of a pointer. That should also work.
With either solution the idea is to have it so the device can "know" the state of its associated switch.
I don't know if it's the 18 hours I've been awake or if I just am not getting it...but I think my lack of understanding involves this line:
device(toggle* pt): p_tog(pt){}// constructor takes a pointer as argument

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;

class toggle//the switch
{
public:
    void set(bool b){x = b;}
    bool call(){return x;}
private:
    bool x;
};

class device//controlled by toggle(switch)
{
public:
    device(toggle* pt): p_tog(pt){}// constructor takes a pointer as argument
    bool call(){ return p_tog->call(); }// must call call() since x is private
private:
    toggle* p_tog;// pointer to a toggle
};

int main()
{
    device tlight;

    tlight.set(1);
    cout << "light is on: "<< tlight.call() << endl; // light is on

    tlight.set(0);
    cout << "light is off: " << tlight.call() << endl; // light is off

    tlight.flip();
    cout << "light state: " << tlight.call() << endl;

    cout << endl;

    return 0;
}


I am getting these errors:

G:\CodeBlocks-Programs\Switches\main.cpp||In function 'int main()':|
G:\CodeBlocks-Programs\Switches\main.cpp|39|error: no matching function for call to 'device::device()'|
G:\CodeBlocks-Programs\Switches\main.cpp|31|note: candidates are: device::device(toggle*)|
G:\CodeBlocks-Programs\Switches\main.cpp|29|note: device::device(const device&)|
G:\CodeBlocks-Programs\Switches\main.cpp|41|error: 'class device' has no member named 'set'|
G:\CodeBlocks-Programs\Switches\main.cpp|44|error: 'class device' has no member named 'set'|
G:\CodeBlocks-Programs\Switches\main.cpp|47|error: 'class device' has no member named 'flip'|
||=== Build finished: 4 errors, 0 warnings (0 minutes, 0 seconds) ===|


Sometimes I wonder if programming is my thing. :p
But I refuse to give up. Programming has actually helped me in other areas of my life. A whole new way of thinking.
Yay! My brain must of found that extra oomph I needed to figure it out.

1
2
toggle tlight;//Why do I create the switch first? Counterintuitive to me
    device light( &tlight);//associating device to a toggle? 


That works. Also, I took out the flip, temporarily.

Thanks guys. I just wish I understood why that works like that. I feel like I am missing a lot here. :(
Maybe someone could explain it a little? I am referring to the act of associating tlight to light, of course.

Thanks.

P.S. This the finished alpha. What do you think?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
using namespace std;

class toggle//the switch
{
public:
    void set(bool b){x = b;}
    bool call()const{return x;}
    void flip(){if(x==true)x=false;else x=true;}
private:
    bool x;
};

class device//controlled by toggle(switch)
{
public:
    device(toggle* pt): p_tog(pt){}// constructor takes a pointer as argument
    bool call()const{ return p_tog->call(); }// must call call() since x is private
private:
    toggle* p_tog;// pointer to a toggle
};

int main()
{
    toggle tlight;//Why do I create the switch first? Counterintuitive to me
    device light( &tlight);//associating device to a toggle?

    tlight.set(1);
    cout << "light is on: "<< tlight.call() << endl; // light is on

    tlight.set(0);
    cout << "light is off: " << tlight.call() << endl; // light is off

    tlight.set(1);
    cout << "light is on: "<< tlight.call() << endl; // light is on

    tlight.flip();
    cout << "light flipped: " << tlight.call() << endl;//toggle flipped

    tlight.flip();
    cout << "light flipped: " << tlight.call() << endl;//toggle flipped

    cout << endl;

    return 0;
}


I plan on making it idiot proof next. Practice practice practice...
Last edited on
closed account (D80DSL3A)
That's cool but your code tests just the switch, not the lights.
You may want to see if the light follows the state of the switch.
How about a switch that controls several lights at once? Here's some code which does that:

I have added a constructor to the toggle class so that a switch is created in the off position by default: toggle(bool state = false): x(state){}// default state is "off"
The main function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main()
{
    // a switch controlling a single light
    toggle tlight;
    device light( &tlight);// associate toggle with device

    tlight.set(1);
    // here the light is tested, not the switch
    cout << light.call() << " ";// light is on

    tlight.set(0);
    cout << light.call() << " ";// light is off
    cout << endl;

    // a switch controlling several lights
    toggle t2;// the switch will be created in the "off" position
    device lightArray[] = { device(&t2), device(&t2), device(&t2) };// 3 lights controlled by t2

    // check the state of the lights
    cout << endl << "The lights are ";
    for(int i=0; i<3; ++i)
        cout << lightArray[i].call();

    // turn the switch on
    t2.set(1);

    // check the lights again
    cout << endl << "The lights are ";
    for(int i=0; i<3; ++i)
        cout << lightArray[i].call();

    cout << endl;
    return 0;
}

I think I understand now.

toggle(bool state = false): x(state){}

toggle <- is the constructor identifier
(bool state = false) <- is creating a boolean variable called state
: <- I have no idea what to call this
x(state) <- changes the toggle member variable x to false

Is that right?
I have just thought of another possibility...

I want to have panels of switches...

Each panel will have a set of switches and each switch would control one or more light...

How would I set up a class or whatever to handle a set of its own switches?
closed account (D80DSL3A)
About the constructor. You are right about most of it.
(bool state = false) <- is creating a boolean variable called state

A default value of false is also being defined here. This way the constructor will also work with no argument supplied.
Eg:
toggle t1(true); creates t1 with x = true.
toggle t1; default value of state = false will be used. x = false will result.

About the panel concept. What aspects of a panel do you wish to model?
If a panel is no more than a set of toggles then an array of toggles may do just fine to represent the panel.
toggle panel1[5]; panel1 is an array of 5 toggles.

I went a bit further and added a connected load data member to the toggle class myself:
double conn_load;// load served by switch in amps
I also added a member to the device class for the device load:
double I;// current drawn by device in amps
The device constructor sets everything up:
1
2
3
4
device(double current, toggle* pS): I(current), pSw(pS)// this is initialization list style
{ 
    pSw->conn_load += I;// the toggles connected load is increased
}


Then my panel class has a double load; member = sum of connected loads for the switches that are in the "on" state. Doing this makes a panel function necessary so that the panel load gets adjusted when a toggle is switched on or off:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// This function is used to change the switch settings in the panel
bool panel::set_sw_state(int space, bool turn_on)// space = switch # in panel
{
    if(space>=0 && space <N)// validate the space #
    {
        if( turn_on && !sw[space].on )// turn on a switch which was off
        {
            sw[space].on = true;
            load += sw[space].conn_load;// adjust the panel load
        }
        else if( !turn_on && sw[space].on )// turn off a switch which was on.
        {
            sw[space].on = false;
            load -= sw[space].conn_load;// adjust the panel load
        }
        return sw[space].on;
    }
    return false;// invalid space # was given
}

Example: panel1.set_sw_state(2, true);// turns switch #2 on

I'm thinking of adding fuse protection for the switches in the panel. Each toggle would have a member: double fuse_rating;. A switch would "trip" (turn off) if the connected load exceeds the fuse rating.

You could make it as complicated as you wish!

EDIT: Details added.
Last edited on
I just read through all of the posts again. It seems I have processed this stuff in my "cpu" long enough to understand. Thanks for all of your help, guys. Although it is a little unwieldy in my head as of yet, with some practice I will be able to use it more easily. Again, thank you very much.
Topic archived. No new replies allowed.